Appearance
轮播图
版本说明
时间 | 修改人 | 备注 |
---|---|---|
2025-04-24 | YG | 补充文档 |
一、轮播图设计规范
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 | 自动轮播间隔,单位为 ms | number/string | - |
duration | 动画时长,单位为 ms | number/string | 500 |
initial-swipe | 初始位置索引值 | number/string | 0 |
width | 滑块宽度,单位为 px | number/string | auto |
height | 滑块高度,单位为 px | number/string | auto |
loop | 是否开启循环播放 | boolean | true |
show-indicators | 是否显示指示器 | boolean | true |
vertical | 是否为纵向滚动 | boolean | false |
touchable | 是否可以通过手势滑动 | boolean | true |
stop-propagation | 是否阻止滑动事件冒泡 | boolean | true |
lazy-render | 是否延迟渲染未展示的轮播 | boolean | false |
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>