Swiper 轮播图
数据驱动的图片轮播:自动播放、衔接循环、手势滑切原生承接;卡片式轮播(前后边距露出相邻项 + 非当前项缩放)与指示器点 / 线 / 数字 / 标题 / 页码五形态并集内置。list 同时接受字符串数组(图片地址)与对象数组(经 srcKey / titleKey 映射地址与标题),#default 插槽可整页接管内容(视频、图文卡片等任意轮播体)。
平台兼容性
| App(Android/iOS) | Web | 微信小程序 | 鸿蒙 |
|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ |
已知限制:微信小程序基础库缺陷——
autoplay为 false 时动态修改interval会意外启用自动播放(原生组件层缺陷,与本组件无关)。关闭自动播放后请勿动态改interval。
基本使用
list 传图片地址数组即可轮播(默认自动播放,间隔 3 秒):
<n-swiper :list="['https://cdn.example.com/a.jpg', 'https://cdn.example.com/b.jpg', 'https://cdn.example.com/c.jpg']" />
开启指示器(默认圆点形态,悬浮底部居中):
<n-swiper :list="list" indicator />
对象数组与五形态指示器
list 为对象数组时,图片地址取 src-key 指定字段(默认 src)、标题文本取 title-key 指定字段(默认 title):
<n-swiper :list="list" src-key="pic" title-key="caption" indicator indicator-mode="title" />
indicator-mode 五形态:
| 形态 | 说明 |
|---|---|
| dot | 等圆点,当前项高亮(默认) |
| line | 线条,当前项加长 |
| number | 数字索引 1 2 3…,当前项高亮加粗 |
| title | 整宽贴底标题条,显示当前项标题(缺失标题字段显示占位短横) |
| page | 右下角页码胶囊 N/总数 |
dot / line / number 形态点按指示位即跳到该项;title / page 不响应点击。指示器配色用 indicator-active-color / indicator-inactive-color,定位与整体样式用 indicator-style 行内覆盖(如 "bottom:20px;left:16px")。
卡片式轮播
previous-margin / next-margin 露出前 / 后一项,circular 衔接循环,scale 让非当前项缩小(配合边距组成卡片视觉):
<n-swiper
:list="list"
:circular="true"
:previous-margin="40"
:next-margin="40"
:scale="0.9"
:radius="8"
indicator
/>
受控与事件
current 受控:外部赋值即切换到该项(越界自动钳制);用户滑动经 change 上报、不回写 current(回写由使用方决定):
<n-swiper :list="list" :current="page" @change="onChange" @click="onItemClick" />
// { current: 2, source: 'autoplay' | 'touch' | ''(外部改 current 驱动) }
function onChange(e: NSwiperChangeEvent) { page.value = e.current; }
// { item: { src, title }, index: 2 } —— item 为映射产物
function onItemClick(e: NSwiperClickEvent) { /* 跳转详情等 */ }
点击轮播项图片发送 click(载荷 { item, index });#default 插槽接管内容后点击语义由插槽内容自管、不再上发。
插槽接管
#default 插槽提供时整页内容自行渲染(作用域 item / index),内置图片不再产出;#indicator 插槽整体接管指示器(作用域 current / total):
<n-swiper :list="list" :autoplay="false" indicator>
<template #default="{ item, index }">
<view class="banner-card"><text class="banner-title">{{ item.title }}</text></view>
</template>
<template #indicator="{ current, total }">
<text class="pager">{{ current + 1 }}/{{ total }}</text>
</template>
</n-swiper>
加载态与定制通道
loading 开启时轮播区覆盖居中加载指示器(数据未就绪时用);bg-color 设置图片未铺满时的底色。定制通道三层:主题令牌(见下表)> 根节点 custom-class / custom-style > indicator-style 行内样式。
机制对照表(参考实现取舍)
| 机制 | 参考做法 | 本库做法 | 分歧理由 |
|---|---|---|---|
| 滑动引擎 | 一源自实现手势(transform 跟手 + 惯性 + 边界全自管);另两源封装原生 swiper | 原生 swiper 承接 | 同代参考均封装原生;原生手势 / 惯性 / 循环 / 自动播放的一致性与性能远超自实现,自实现是参考库 vue2 时代产物 |
| 指示器形态 | 一源内置点 / 线两形态 + 独立指示器组件;一源包裹容器 + 点 / 数字 / 标题 / 页码四形态 | 五形态并集内置 + #indicator 插槽整体接管 | 形态取并集;指示器只在轮播场景使用,独立组件需手动同步 current 与定位,内置 + 插槽对使用者更简(插槽即全定制通道,覆盖独立组件场景) |
| 指示器点按跳页 | 一源指示位点击切页 | dot / line / number 点按跳页(经游标驱动原生动画,change 主动上发 source 空串) | 沿用参考交互;跳页动画与手势滑切同链路 |
| 卡片式 | 一源 mode=round 开关 + scale;一源前后边距 props;一源原生 previous-margin + 应用层缩放 | previousMargin / nextMargin + scale 组合 | 两源同模型;显式组合避免布局开关与边距 props 的耦合冲突 |
| 标题条 | 一源 showTitle 独立开关 + 键名;一源指示器标题形态 + field 键名 | indicatorMode="title" + titleKey | 同功能收为指示器形态之一,避免标题条与指示器并存的双开关语义纠缠 |
| 数据键名映射 | 各源字段名不一(url / pic / title / text) | srcKey / titleKey(默认 src / title) | 键名映射先例沿用;默认字段名取通用词 |
| 受控链 | current prop + change | 同款;越界钳制;程序驱动跳页的 change 由组件主动上发(source 空串)、用户滑动与自动播放走原生回执(source 保留原生值 autoplay / touch)——H5 端原生对程序改 current 不回执 change,组件补齐后三端恒单发(原生端重复回执被游标等值守卫挡下) | source 是原生回执的有价值信息,保留给使用者;程序驱动回执三端一致是组件职责 |
| 点击项事件 | 一源 item-tap(index);一源 click | click 载荷 { item, index }(item 为映射产物) | 同时给数据与下标;与库内标签页事件载荷同构 |
| disableTouch | 一源提供(自实现手势的开关) | 原生 disable-touch 承接 | 同语义原生化 |
| loading | 一源提供(加载遮罩) | 覆盖层 + 内置加载指示器(复用库内加载组件) | 同功能复用库件 |
| vertical | 四源 API 面均未暴露 | 不收录 | 原生虽支持但无参考依据,不自行创造 API |
| currentItemId | 一源提供(项 id 定位) | 不收录 | current 数字定位同功能;list 驱动模式下项无稳定 id,插槽模式使用者自管 |
| displayMultipleItems / easingFunction / acceleration | 一源透传 | 不收录 | uni-app x 原生 swiper 支持面无实据(官方示例工程全量无一处使用),绑不支持属性必产生编译告警 |
| indicatorStyle 双类型 | 一源 string | object | 统一 string | 行内样式通道全库统一 string |
| transition / animationfinish 事件 | 三源组件 API 面均未暴露 | 不收录 | 无参考依据;滑切回执 change 已覆盖主场景 |
| 实例方法 | 四源均无 | 无 | 受控 current 覆盖程序化定位 |
API
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| list | 轮播项列表:字符串数组(直接作图片地址),或对象数组(地址取 item[srcKey]、标题取 item[titleKey]) | string[] | UTSJSONObject[] | [] |
| src-key | list 为对象数组时,图片地址的属性名 | string | src |
| title-key | list 为对象数组时,标题文本的属性名(title 形态指示器显示该字段);缺失字段的项显示占位短横 | string | title |
| height | 轮播高度;数字 px 或 px/rpx 字符串 | string | number | 130 |
| radius | 图片与轮播容器的圆角;数字 px 或 px/rpx 字符串,0 为直角 | string | number | 0 |
| img-mode | 图片裁剪缩放模式(image 原生 mode) | string | aspectFill |
| autoplay | 自动播放;微信端有基础库缺陷——autoplay 为 false 时改动 interval 会意外启用自动播放,关自动播放后请勿动态改 interval | boolean | true |
| interval | 自动播放间隔(毫秒) | number | 3000 |
| duration | 切换动画时长(毫秒) | number | 300 |
| circular | 衔接循环播放(末项接首项) | boolean | false |
| current | 当前项下标(受控):外部赋值即切换到该项(越界钳制);用户滑动时经 change 上报、不回写本值 | number | 0 |
| previous-margin | 前边距(露出前一项):卡片式轮播用;数字 px 或 px/rpx 字符串 | string | number | 0 |
| next-margin | 后边距(露出后一项):卡片式轮播用;数字 px 或 px/rpx 字符串 | string | number | 0 |
| disable-touch | 禁用用户滑动手势(自动播放与外部 current 驱动不受影响) | boolean | false |
| scale | 非当前项缩放系数:小于 1 时非当前项按该系数缩放(配合前后边距组成卡片式轮播),1 为不缩放 | number | 1 |
| indicator | 是否显示指示器 | boolean | false |
| indicator-mode | 指示器形态:dot 圆点 / line 线条 / number 数字索引 / title 标题条 / page 页码胶囊 | string | dot |
| indicator-active-color | 指示器激活色(当前点 / 线 / 数字色) | string | #ffffff |
| indicator-inactive-color | 指示器非激活色 | string | rgba(255,255,255,0.4) |
| indicator-style | 指示器行内样式(覆盖默认定位与间距,如 bottom:20px;left:16px);title / page 形态的底色与文字色同样可覆盖 |
string | — |
| loading | 加载态:轮播区覆盖居中加载指示器(数据未就绪时用) | boolean | false |
| bg-color | 轮播区背景色(图片未铺满 / 加载中时的底色);空串取次级表面色(随深浅主题) | string | — |
| custom-class | 挂到根节点的额外 class(类需定义在组件样式表内) | string | — |
| custom-style | 根节点行内样式,如 margin:12px;拼接在内部样式之后 |
string | — |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| change | 轮播切换时触发(用户滑动 / 自动播放 / 指示器点按与外部 current 驱动的跳页落定) | { current: number, source: string } |
| click | 点击轮播项图片时触发(#default 插槽接管内容后不再上发) | { item: { src, title }, index: number } |
Slots
| 插槽名 | 说明 | 作用域参数 |
|---|---|---|
| default | 整页轮播内容接管(提供后内置图片与 click 不再产出) | { item: { src, title }, index: number } |
| indicator | 指示器整体接管 | { current: number, total: number } |