Vue3+ts+splidejs轮播插件各种效果

721 阅读3分钟

SplideJS 是一个轻量级且高度可定制的轮播库,它为开发者提供了许多优势,尤其是在构建响应式和高性能的网页应用时。以下是 SplideJS 的一些主要优势:splidejs 文档

  1. 轻量级

    • SplideJS 的体积非常小,这使得它加载速度快,适合用于对性能有较高要求的项目。
  2. 易于使用

    • 提供了简单易懂的 API 和详细的文档,即使是初学者也能快速上手。
  3. 高度可定制

    • 用户可以根据需求调整各种设置,包括布局、动画效果等,以适应不同的设计风格。
  4. 良好的浏览器兼容性

    • 支持多种现代浏览器,并向下兼容部分旧版本浏览器,确保了广泛的适用性。
  5. 触摸友好

    • 优化了在移动设备上的滑动体验,支持触摸操作,增强了移动端用户的交互体验。
  6. 丰富的插件系统

    • 通过插件可以扩展更多功能,如懒加载、无限循环等,满足不同场景下的需求。
  7. 响应式设计

    • 自动适应不同屏幕尺寸,帮助创建美观且实用的响应式网站或应用。

安装

# pnpm安装 其他方式后续文章默认都是pnpm 吧 其他安装方式都是一样的 npm yarn 一律不再反复介绍了
pnpm add @splidejs/splide

基础使用

效果图 普通轮播

image.png

代码参考

<template>
  <div class="splide" ref="splide">
    <div class="splide__track">
      <ul class="splide__list">
        <li class="splide__slide" v-for="(slide, index) in slides" :key="index">
          <img :src="slide.image" :alt="slide.alt" />
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { Splide } from '@splidejs/splide'
import '@splidejs/splide/css/sea-green'

interface Slide {
  image: string
  alt: string
}

const slides = ref<Slide[]>([
  { image: 'https://picsum.photos/800/400?random=1', alt: 'Image 1' },
  { image: 'https://picsum.photos/800/400?random=2', alt: 'Image 2' },
  { image: 'https://picsum.photos/800/400?random=3', alt: 'Image 3' },
])

const splide = ref<Splide | null>(null)

onMounted(() => {
  splide.value = new Splide('.splide', {
    type: 'loop',
    perPage: 1, // 页面中要显示的幻灯片数量
    autoplay: true, // 是否激活自动播放
    interval: 2000, // 自动播放的时间间隔
    lazyLoad: 'nearby', // 懒加载策略
    width: '80%', // 幻灯片的宽度
    arrows: false, // 两个分页箭头 上一张下一张
    // pagination: false, // 页码指示器
    paginationDirection: 'ltr', // 分页器方向
  }).mount()
})
</script>

<style scoped>
.splide {
  width: 100%;
}
.splide__slide {
  text-align: center;
}
.splide__slide img {
  max-width: 100%;
  height: auto;
}
</style>

效果二 带缩略图导航的图片轮播

image.png

代码参考

<template>
  <div>
    <div class="splide" ref="splide-box" id="splide-box">
      <div class="splide__track">
        <ul class="splide__list">
          <li
            class="splide__slide"
            v-for="(slide, index) in slides"
            :key="index"
          >
            <img :src="slide.image" :alt="slide.alt" />
          </li>
        </ul>
      </div>
    </div>

    <div class="splide thumbnail" ref="thumbnailSplide" id="thumbnailSplide">
      <div class="splide__track">
        <ul class="splide__list">
          <li
            class="splide__slide"
            v-for="(slide, index) in slides"
            :key="index"
          >
            <img :src="slide.image" :alt="slide.alt" class="thumbnail-image" />
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { Splide } from '@splidejs/splide'
import '@splidejs/vue-splide/css'

interface Slide {
  image: string
  alt: string
}

const slides = ref<Slide[]>([
  { image: 'https://picsum.photos/400/600?random=1', alt: 'Image 1' },
  { image: 'https://picsum.photos/400/600?random=2', alt: 'Image 2' },
  { image: 'https://picsum.photos/400/600?random=3', alt: 'Image 3' },
  { image: 'https://picsum.photos/400/600?random=4', alt: 'Image 3' },
  { image: 'https://picsum.photos/400/600?random=5', alt: 'Image 3' },
  { image: 'https://picsum.photos/400/600?random=6', alt: 'Image 3' },
])

const splideBox = ref<Splide | null>(null)
const thumbnailSplide = ref<Splide | null>(null)

onMounted(() => {
  splideBox.value = new Splide('#splide-box', {
    type: 'fade', // 切换效果为淡入淡出
    heightRatio: 0.5,
    arrows: false,
  }).mount()

  thumbnailSplide.value = new Splide('#thumbnailSplide', {
    fixedWidth: 100,
    fixedHeight: 64,
    isNavigation: true,
    gap: 10,
    focus: 'center',
    pagination: false,
    cover: true,
  }).mount()

  // 同步主轮播和缩略图轮播
  splideBox.value.sync(thumbnailSplide.value as Splide)
})
</script>

<style scoped>
.splide {
  margin-bottom: 1rem;
}
.splide__slide {
  text-align: center;
}
.splide__slide img {
  /* max-width: 100%;
  height: auto; */
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.thumbnail {
  background: #f8f8f8;
  padding: 10px;
  /* 如果图片较少加上这两行会比较合适 多的话不需要 */
  display: flex; /* 居中缩略图 */
  justify-content: center;
}
.thumbnail-image {
  cursor: pointer; /* 鼠标指针变为手势 */
  opacity: 0.7;
}
.thumbnail-image:hover {
  opacity: 1; /* 悬停时增加透明度 */
}
</style>

效果三 进度条

image.png

代码参考

<template>
  <div>
    <div class="splide" ref="splideBox" id="splide-box">
      <div class="splide__track">
        <ul class="splide__list">
          <li
            class="splide__slide"
            v-for="(slide, index) in slides"
            :key="index"
          >
            <img :src="slide.image" :alt="slide.alt" />
          </li>
        </ul>
      </div>
    </div>
    <!-- 进度条 -->
    <div class="progress">
      <div class="progress-bar" ref="progressBar"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import Splide from '@splidejs/splide'
import '@splidejs/vue-splide/css'

const slides = ref([
  { image: 'https://picsum.photos/400/500?random=1', alt: 'Image 1' },
  { image: 'https://picsum.photos/400/500?random=2', alt: 'Image 2' },
  { image: 'https://picsum.photos/400/500?random=3', alt: 'Image 3' },
])

const splideBox = ref<Splide | null>(null)
const progressBar = ref<HTMLDivElement | null>(null)

onMounted(() => {
  splideBox.value = new Splide('#splide-box', {
    type: 'loop',
    heightRatio: 0.5,
    arrows: true,
    autoplay: true,
    interval: 2000,
  }).mount()

  // 更新进度条
  splideBox.value.on('mounted move', () => {
    const totalSlides = splideBox.value!.length
    const currentIndex = splideBox.value!.index
    const progress = ((currentIndex + 1) / totalSlides) * 100
    if (progressBar.value) {
      progressBar.value.style.width = `${progress}%`
    }
  })
})
</script>

<style scoped>
.progress {
  width: 100%;
  height: 5px;
  background-color: #e0e0e0;
  margin-top: 10px;
}

.progress-bar {
  width: 0;
  height: 100%;
  background-color: #76c7c0;
  transition: width 0.3s ease;
}
</style>

特效参考