npm.io
1.0.3 • Published 5d ago

@punish/carousel

Licence
MIT
Version
1.0.3
Deps
0
Size
34 kB
Vulns
0
Weekly
0

Slider 组件

一个功能强大的轮播滑块组件,支持触摸拖拽、无限循环、自定义样式和 RTL(从右到左)布局。

功能特性

  • 轻量级,仅依赖 Vue 3
  • 支持触摸/鼠标拖拽交互
  • 无限循环滚动
  • 支持初始索引设置
  • 响应式设计
  • 完全可自定义样式
  • 支持 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 T[] [] 要显示的数据数组
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 }">
            <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>

注意事项

  1. 无限循环:当项目数量大于等于 displayCount 时,组件会自动启用无限循环功能。
  2. 触摸交互:组件支持触摸和鼠标拖拽,可以通过 threshold 属性调整触发切换的阈值。
  3. 响应式:组件会根据容器宽度自动调整滑块大小。
  4. RTL 支持:在 RTL 模式下,所有交互(拖拽、动画、分页器)都会自动适配从右到左的布局。

浏览器兼容性

  • Chrome/Edge (最新版本)
  • Firefox (最新版本)
  • Safari (最新版本)
  • 移动端浏览器(支持触摸事件)

License

MIT

Keywords