@punish/carousel
@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
Related Packages
embla-carousel
A lightweight carousel library with fluid motion and great swipe precision
1,138,077,498
8,453
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.0.14 | ^3.5.0 | MIT | |
| 1.0.13 | ^3.5.0 | MIT | |
| 1.0.12 | ^3.5.0 | MIT | |
| 1.0.11 | ^3.5.0 | MIT | |
| 1.0.10 | ^3.5.0 | MIT | |
| 1.0.8 | ^3.5.0 | MIT | |
| 1.0.7 | ^3.5.0 | MIT | |
| 1.0.6 | ^3.5.0 | MIT | |
| 1.0.5 | ^3.5.0 | MIT | |
| 1.0.4 | ^3.5.0 | MIT | |
| 1.0.3 | ^3.5.0 | MIT | |
| 1.0.2 | ^3.5.0 | MIT | |
| 1.0.1 | ^3.5.0 | MIT | |
| 1.0.0 | ^3.5.0 | MIT |