@punish/carousel
v1.0.14
Published
vue3 轮播组件
Maintainers
Readme
@punish/carousel
一个功能强大的 Vue 3 轮播滑块组件,支持触摸拖拽、无限循环、自定义样式和 RTL(从右到左)布局。
📖 文档
完整的 API 文档和在线演示:Documents
✨ 功能特性
- 🚀 轻量级,仅依赖 Vue 3
- ✨ 支持触摸/鼠标拖拽交互
- 🔄 无限循环滚动
- ▶️ 支持自动轮播(
autoplay+delay) - 🎯 支持初始索引设置
- 📱 响应式设计
- 🎨 完全可自定义样式
- 🌐 支持 RTL(从右到左)布局
- ⚡ 平滑的动画过渡
- 🎛️ 内置分页器
- 🎚️ 支持暴露宽度显示相邻项
- 🔀 支持显示多个项目
安装
npm install @punish/carousel注意: import "@punish/carousel/dist/style.css"; // 如果需要样式 (SSR OR SSG 建议引入, 避免页面样式闪烁)
优势: 无需手动引入样式文件 且 按需加载
基础使用
<template>
<Slider :items="items" @change="handleChange">
<template #default="{ item, active }">
<div :class="{ 'item-active': active }">
{{ item }}
</div>
</template>
</Slider>
</template>
<script setup>
import { Slider } from "@punish/carousel";
const items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"];
const handleChange = (index) => {
console.log("当前索引:", index);
};
</script>Props 属性
| 属性名 | 类型 | 默认值 | 说明 |
| --------------------------- | ---------------- | ----------- | -------------------------------------------- |
| items | Array | [] | 要显示的数据数组 |
| autoplay | boolean | false | 是否自动播放 |
| delay | number | 3000 | 自动播放间隔(毫秒) |
| initialIndex | number | 0 | 初始显示的索引位置 |
| threshold | number | 20 | 拖拽阈值(像素),超过此值触发切换 |
| gap | number | 0 | 滑块之间的间距(像素) |
| duration | number | 300 | 动画持续时间(毫秒) |
| itemClass | string | '' | 列表项的自定义类名 |
| activeItemClass | string | '' | 活动项的自定义类名 |
| displayCount | number | 1 | 同时显示的滑块数量 |
| exposureWidth | number | 0 | 暴露宽度,显示相邻项的部分宽度 |
| paginationClass | string | '' | 分页器容器的自定义类名 |
| paginationItemClass | string | '' | 分页器项的自定义类名 |
| activePaginationItemClass | string | '' | 活动分页器项的自定义类名 |
| paginationGap | number | 24 | 分页器项之间的间距(像素) |
| paginationVisible | boolean | true | 是否显示分页器 |
| dir | 'ltr' \| 'rtl' | undefined | 布局方向,ltr 为从左到右,rtl 为从右到左 |
Events 事件
| 事件名 | 参数 | 说明 |
| -------- | ----------------- | ------------------ |
| change | (index: number) | 当前索引变化时触发 |
Methods 方法
通过 ref 可以访问以下方法:
| 方法名 | 参数 | 说明 |
| -------- | ----------------- | -------------- |
| moveTo | (index: number) | 移动到指定索引 |
| next | () | 移动到下一项 |
| prev | () | 移动到上一项 |
Slots 插槽
| 插槽名 | 作用域参数 | 说明 |
| --------- | ------------------------------ | -------------- |
| default | { item: T, active: boolean } | 自定义滑块内容 |
使用示例
基础示例
<template>
<Slider :items="items">
<template #default="{ item, active }">
<div class="slide-item" :class="{ active }">
{{ item }}
</div>
</template>
</Slider>
</template>
<script setup>
import { Slider } from "@punish/carousel";
const items = ["Slide 1", "Slide 2", "Slide 3"];
</script>
<style>
.slide-item {
width: 100%;
height: 200px;
display: flex;
align-items: center;
justify-content: center;
background: #f0f0f0;
border-radius: 8px;
}
.slide-item.active {
background: #007bff;
color: white;
}
</style>设置初始索引
<template>
<Slider :items="items" :initial-index="2">
<template #default="{ item }">
<div class="slide-item">{{ item }}</div>
</template>
</Slider>
</template>自定义间距和动画
<template>
<Slider :items="items" :gap="20" :duration="500">
<template #default="{ item }">
<div class="slide-item">{{ item }}</div>
</template>
</Slider>
</template>显示多个项目
<template>
<Slider :items="items" :display-count="3" :exposure-width="50">
<template #default="{ item, active, index }">
<div class="slide-item" :class="{ active }">
{{ item }}
</div>
</template>
</Slider>
</template>
<style>
.slide-item {
height: 150px;
background: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
}
.slide-item.active {
background: #007bff;
color: white;
transform: scale(1.05);
}
</style>使用方法控制
<template>
<div>
<Slider ref="sliderRef" :items="items">
<template #default="{ item }">
<div class="slide-item">{{ item }}</div>
</template>
</Slider>
<div class="controls">
<button @click="prev">上一个</button>
<button @click="next">下一个</button>
<button @click="moveTo(0)">回到第一个</button>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { Slider } from "@punish/carousel";
const sliderRef = ref(null);
const items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"];
const prev = () => sliderRef.value?.prev();
const next = () => sliderRef.value?.next();
const moveTo = (index) => sliderRef.value?.moveTo(index);
</script>RTL(从右到左)布局
<template>
<Slider :items="items" dir="rtl">
<template #default="{ item }">
<div class="slide-item">{{ item }}</div>
</template>
</Slider>
</template>自定义样式
<template>
<Slider
:items="items"
item-class="custom-item"
active-item-class="custom-active"
pagination-class="custom-pagination"
pagination-item-class="custom-dot"
active-pagination-item-class="custom-dot-active"
>
<template #default="{ item, active }">
<div class="slide-content">
<h3>{{ item.title }}</h3>
<p>{{ item.description }}</p>
</div>
</template>
</Slider>
</template>
<script setup>
import { Slider } from "@punish/carousel";
const items = [
{ title: "标题 1", description: "描述 1" },
{ title: "标题 2", description: "描述 2" },
{ title: "标题 3", description: "描述 3" },
];
</script>
<style>
.custom-item {
transition: all 0.3s ease;
}
.custom-active {
transform: scale(1.1);
}
.custom-pagination {
gap: 16px;
}
.custom-dot {
width: 40px;
height: 4px;
background: #ddd;
border-radius: 2px;
}
.custom-dot-active {
background: #007bff;
}
</style>隐藏分页器
<template>
<Slider :items="items" :pagination-visible="false">
<template #default="{ item }">
<div class="slide-item">{{ item }}</div>
</template>
</Slider>
</template>监听变化事件
<template>
<Slider :items="items" @change="handleChange">
<template #default="{ item }">
<div class="slide-item">{{ item }}</div>
</template>
</Slider>
<p>当前索引: {{ currentIndex }}</p>
</template>
<script setup>
import { ref } from "vue";
import { Slider } from "@punish/carousel";
const items = ["Item 1", "Item 2", "Item 3"];
const currentIndex = ref(0);
const handleChange = (index) => {
currentIndex.value = index;
console.log("切换到:", index);
};
</script>注意事项
- 无限循环:当项目数量大于等于
displayCount时,组件会自动启用无限循环功能。 - 触摸交互:组件支持触摸和鼠标拖拽,可以通过
threshold属性调整触发切换的阈值。 - 响应式:组件会根据容器宽度自动调整滑块大小。
- RTL 支持:在 RTL 模式下,所有交互(拖拽、动画、分页器)都会自动适配从右到左的布局。
浏览器兼容性
- Chrome/Edge (最新版本)
- Firefox (最新版本)
- Safari (最新版本)
- 移动端浏览器(支持触摸事件)
License
MIT
