Skip to content

轮播图

版本说明

时间修改人备注
2025-04-24YG补充文档

一、轮播图设计规范

1. 基础规范

  • 尺寸规范

    • 轮播图宽度建议设置为100%或固定宽度
    • 高度根据实际内容确定,建议保持宽高比例一致
    • 移动端建议高度不超过屏幕高度的40%
  • 内容规范

    • 轮播内容应清晰可辨,避免过于复杂的背景
    • 文字内容应简洁明了,避免过多文字
    • 图片应优化压缩,建议单张不超过200KB
  • 交互规范

    • 自动轮播间隔建议3000-5000ms
    • 轮播切换动画时长建议300-500ms
    • 支持手势滑动切换
    • 点击轮播图应有明确的响应

2. 指示器规范

  • 样式规范

    • 指示器应与轮播内容形成对比,确保可见性
    • 当前页指示器应有明显的状态区分
    • 指示器大小适中,建议直径8-12rpx
    • 指示器间距建议为指示器直径的1.5-2倍
  • 位置规范

    • 横向轮播指示器通常位于底部居中
    • 垂直轮播指示器通常位于右侧居中
    • 指示器与轮播边缘保持适当间距,建议20-30rpx

二、轮播图实现方式

1. 使用vant组件(H5端推荐)


代码示例

vue
<template>
  <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
    <van-swipe-item v-for="(item, index) in bannerList" :key="index" @click="handleBannerClick(item)">
      <img :src="item.imageUrl" class="banner-img" />
    </van-swipe-item>
  </van-swipe>
</template>

<script setup>
import { ref } from 'vue';

const bannerList = ref([
  { id: 1, imageUrl: 'https://example.com/banner1.jpg', linkUrl: '/pages/detail/detail?id=1' },
  { id: 2, imageUrl: 'https://example.com/banner2.jpg', linkUrl: '/pages/detail/detail?id=2' },
  { id: 3, imageUrl: 'https://example.com/banner3.jpg', linkUrl: '/pages/detail/detail?id=3' },
]);

const handleBannerClick = (item) => {
  uni.navigateTo({
    url: item.linkUrl
  });
};
</script>

<style scoped>
.my-swipe {
  height: 300rpx;
}
.banner-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
</style>

Swipe Props:

参数说明类型默认值
autoplay自动轮播间隔,单位为 msnumber/string-
duration动画时长,单位为 msnumber/string500
initial-swipe初始位置索引值number/string0
width滑块宽度,单位为 pxnumber/stringauto
height滑块高度,单位为 pxnumber/stringauto
loop是否开启循环播放booleantrue
show-indicators是否显示指示器booleantrue
vertical是否为纵向滚动booleanfalse
touchable是否可以通过手势滑动booleantrue
stop-propagation是否阻止滑动事件冒泡booleantrue
lazy-render是否延迟渲染未展示的轮播booleanfalse
indicator-color指示器颜色string#1989fa

Swipe Events

事件名说明回调参数
change每一页轮播结束后触发index 当前页的索引

SwipeItem Events

事件名说明回调参数
click点击时触发event: MouseEvent

Swipe 方法

通过 ref 可以获取到 Swipe 实例并调用实例方法.

事件名说明参数
prev切换到上一轮播-
next切换到下一轮播-
swipeTo切换到指定位置index: number, options: SwipeToOptions
resize外层元素大小或组件显示状态变化时,可以调用此方法来触发重绘-

基础用法

  • 每个 SwipeItem 代表一张轮播卡片,可以通过 autoplay 属性设置自动轮播的间隔。
vue
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
  <van-swipe-item>1</van-swipe-item>
  <van-swipe-item>2</van-swipe-item>
  <van-swipe-item>3</van-swipe-item>
  <van-swipe-item>4</van-swipe-item>
</van-swipe>

轮播图片懒加载

  • 当 Swipe 中含有图片时,可以通过 lazy-render 属性来开启懒加载模式。在懒加载模式下,只会渲染当前页和下一页。
vue
<van-swipe :autoplay="3000" lazy-render>
      <van-swipe-item v-for="image in images" :key="image">
        <img :src="image" />
      </van-swipe-item>
    </van-swipe>
js
export default {
  setup() {
    const images = [
      "https://fastly.jsdelivr.net/npm/@vant/assets/apple-1.jpeg",
      "https://fastly.jsdelivr.net/npm/@vant/assets/apple-2.jpeg",
    ];
    return { images };
  },
};

监听 change 事件

  • 在每一页轮播结束后,会触发 change 事件。
vue
<van-swipe @change="onChange">
      <van-swipe-item>1</van-swipe-item>
      <van-swipe-item>2</van-swipe-item>
      <van-swipe-item>3</van-swipe-item>
      <van-swipe-item>4</van-swipe-item>
    </van-swipe>
js
export default { setup() { const onChange = (index) => console.log('当前 Swipe
索引:' + index); return { onChange }; }, };

纵向滚动

  • 设置 vertical 属性后滑块会纵向排列,此时需要指定滑块容器的高度。
vue
<van-swipe vertical>
      <van-swipe-item>1</van-swipe-item>
      <van-swipe-item>2</van-swipe-item>
      <van-swipe-item>3</van-swipe-item>
      <van-swipe-item>4</van-swipe-item>
    </van-swipe>

自定义指示器

  • 通过 indicator 插槽可以自定义指示器的样式。
vue
<van-swipe>
  <van-swipe-item>1</van-swipe-item>
  <van-swipe-item>2</van-swipe-item>
  <van-swipe-item>3</van-swipe-item>
  <van-swipe-item>4</van-swipe-item>
  <template #indicator="{ active, total }">
    <div class="custom-indicator">{{ active + 1 }}/{{ total }}</div>
  </template>
</van-swipe>
<style>
.custom-indicator {
  position: absolute;
  right: 5px;
  bottom: 5px;
  padding: 2px 5px;
  font-size: 12px;
  background: rgba(0, 0, 0, 0.1);
}
</style>

vant 文档

https://vant-ui.github.io/vant/v2/#/zh-CN/swipe

2. 使用uni-app原生组件(跨平台推荐)

vue
<template>
  <swiper 
    class="swiper" 
    :indicator-dots="true" 
    :autoplay="true" 
    :interval="3000" 
    :duration="500"
    :circular="true"
    @change="handleChange"
  >
    <swiper-item v-for="(item, index) in bannerList" :key="index" @click="handleBannerClick(item)">
      <image :src="item.imageUrl" class="banner-img" mode="aspectFill"></image>
    </swiper-item>
  </swiper>
</template>

<script setup>
import { ref } from 'vue';

const bannerList = ref([
  { id: 1, imageUrl: 'https://example.com/banner1.jpg', linkUrl: '/pages/detail/detail?id=1' },
  { id: 2, imageUrl: 'https://example.com/banner2.jpg', linkUrl: '/pages/detail/detail?id=2' },
  { id: 3, imageUrl: 'https://example.com/banner3.jpg', linkUrl: '/pages/detail/detail?id=3' },
]);

const handleChange = (e) => {
  console.log('当前轮播索引:', e.detail.current);
};

const handleBannerClick = (item) => {
  uni.navigateTo({
    url: item.linkUrl
  });
};
</script>

<style scoped>
.swiper {
  height: 300rpx;
}
.banner-img {
  width: 100%;
  height: 100%;
}
</style>

三、常见轮播图类型

1. 基础轮播图

适用于展示广告、活动等内容,自动轮播,支持手势滑动。

vue
<swiper 
  class="basic-swiper" 
  :indicator-dots="true" 
  :autoplay="true" 
  :interval="3000" 
  :duration="500"
  :circular="true"
>
  <swiper-item v-for="(item, index) in bannerList" :key="index">
    <image :src="item.imageUrl" class="banner-img" mode="aspectFill"></image>
  </swiper-item>
</swiper>

2. 卡片式轮播图

显示前后卡片的一部分,营造层次感。

vue
<swiper 
  class="card-swiper" 
  :indicator-dots="true" 
  :autoplay="true" 
  :interval="3000" 
  :duration="500"
  :circular="true"
  :previous-margin="50rpx"
  :next-margin="50rpx"
>
  <swiper-item v-for="(item, index) in bannerList" :key="index">
    <view class="card-item">
      <image :src="item.imageUrl" class="card-img" mode="aspectFill"></image>
    </view>
  </swiper-item>
</swiper>

<style scoped>
.card-swiper {
  height: 300rpx;
}
.card-item {
  height: 100%;
  padding: 0 10rpx;
  box-sizing: border-box;
}
.card-img {
  width: 100%;
  height: 100%;
  border-radius: 12rpx;
}
</style>

3. 垂直轮播图

适用于公告、消息等文本内容的展示。

vue
<swiper 
  class="vertical-swiper" 
  :vertical="true" 
  :autoplay="true" 
  :interval="3000" 
  :duration="500"
  :circular="true"
  :indicator-dots="false"
>
  <swiper-item v-for="(item, index) in noticeList" :key="index">
    <view class="notice-item">{{ item.content }}</view>
  </swiper-item>
</swiper>

<script setup>
import { ref } from 'vue';

const noticeList = ref([
  { id: 1, content: '公告内容1' },
  { id: 2, content: '公告内容2' },
  { id: 3, content: '公告内容3' },
]);
</script>

<style scoped>
.vertical-swiper {
  height: 80rpx;
}
.notice-item {
  height: 80rpx;
  line-height: 80rpx;
  padding: 0 20rpx;
  font-size: 28rpx;
  color: #333;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>

4. 自定义指示器轮播图

自定义指示器样式,提升UI效果。

vue
<view class="custom-swiper-container">
  <swiper 
    class="custom-swiper" 
    :autoplay="true" 
    :interval="3000" 
    :duration="500"
    :circular="true"
    :indicator-dots="false"
    @change="handleSwiperChange"
  >
    <swiper-item v-for="(item, index) in bannerList" :key="index">
      <image :src="item.imageUrl" class="banner-img" mode="aspectFill"></image>
    </swiper-item>
  </swiper>
  
  <!-- 自定义指示器 -->
  <view class="custom-indicator">
    <view 
      v-for="(item, index) in bannerList" 
      :key="index"
      class="indicator-dot"
      :class="{ active: currentIndex === index }"
    ></view>
  </view>
</view>

<script setup>
import { ref } from 'vue';

const bannerList = ref([
  { id: 1, imageUrl: 'https://example.com/banner1.jpg' },
  { id: 2, imageUrl: 'https://example.com/banner2.jpg' },
  { id: 3, imageUrl: 'https://example.com/banner3.jpg' },
]);

const currentIndex = ref(0);

const handleSwiperChange = (e) => {
  currentIndex.value = e.detail.current;
};
</script>

<style scoped>
.custom-swiper-container {
  position: relative;
  height: 300rpx;
}
.custom-swiper {
  height: 100%;
}
.banner-img {
  width: 100%;
  height: 100%;
}
.custom-indicator {
  position: absolute;
  bottom: 20rpx;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
}
.indicator-dot {
  width: 12rpx;
  height: 12rpx;
  border-radius: 6rpx;
  background-color: rgba(255, 255, 255, 0.5);
  margin: 0 8rpx;
  transition: all 0.3s;
}
.indicator-dot.active {
  width: 24rpx;
  background-color: #ffffff;
}
</style>