更新记录
1.0.0(2026-08-31) 下载此版本
- 核心手势引擎:发布首个正式版本,内置丝滑物理拖拽手势与 0.05 黄金跟手旋转阻尼。
- 多维空间堆叠:支持配置垂直偏移步长 (
offsetY)、水平偏移步长 (offsetX)、缩放步长 (scaleStep)、错落旋转步长 (rotateStep) 以及透明度渐隐衰减 (fadeStep)。 - 灵活模式支持:支持无限循环翻页 (
loop: true) 与单次滑完判定 (loop: false)。 - 交互防护机制:退场飞出卡片与底层未激活卡片全面隔离事件流 (
pointer-events: none),杜绝误触与穿透形变。 - 丰富插槽透传:支持通过作用域插槽获取
item、dragRatio、dragDirection等实时拖拽动力学数据。 - 完整 API 与实例方法:支持通过 ref 实例方法进行编程式切牌 (
swipe) 与状态归位 (reset)。
平台兼容性
uni-app(3.8.3)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | √ | √ | √ | × | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
jon-stack 卡片堆叠滑动组件
通用高性能卡片堆叠滑动容器,内置丝滑手势拖动与物理联动动画,支持图片背景或纯色背景作为卡片底图,并在上层提供完全自定义内容插槽,可配置任意层叠布局,开箱即用。
适用于「探探式」滑动卡片、商品推荐、图片浏览、短视频推荐等场景。
特性
- 🎯 丝滑手势引擎:内置物理拖拽手势与 0.05 黄金跟手旋转阻尼,拖动、判定、飞出一气呵成
- 🗂 多维空间堆叠:独立配置垂直偏移
offsetY、水平偏移offsetX、缩放scaleStep、错落旋转rotateStep、透明度渐隐fadeStep,任意排列组合 - 🔁 双模式切换:
loop: true无限循环翻页 /loop: false单次滑完并触发end事件 - 🛡 交互隔离防护:退场飞出卡片与底层未激活卡片全面隔离事件流(
pointer-events: none),杜绝误触与穿透形变 - 🎨 背景与插槽叠加:图片背景(
imageKey)或纯色背景(bgKey)作为卡片底图,上层始终渲染完全自定义内容插槽;二者可同时使用,也可以都不设置背景 - 📦 作用域插槽透传:实时获取
item、index、isCurrent、dragRatio、dragDirection等拖拽动力学数据 - 🎛 完整 API:ref 实例方法编程式切牌
swipe()、状态归位reset()
安装
在 HBuilderX 中,将本插件目录(uni_modules/jon-stack)拷贝到项目的 uni_modules 目录下即可。
组件符合 easycom 规范,无需手动 import 与注册,页面中直接使用 <jon-stack /> 标签。
快速上手
<template>
<view class="page">
<jon-stack ref="stackRef" :list="cardList" @change="onChange" @swipe="onSwipe"
@cardClick="onCardClick" @end="onEnd">
<template #default="{ item }">
<view class="card-body">
<text class="card-text">{{ item.title }}</text>
</view>
</template>
</jon-stack>
<view class="actions">
<button @click="swipe('left')">左滑</button>
<button @click="reset">重置</button>
<button @click="swipe('right')">右滑</button>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const stackRef = ref(null)
const cardList = ref([
{ id: 1, title: '卡片 1', image: '/static/1.jpg' },
{ id: 2, title: '卡片 2', bgColor: '#66ccff' },
{ id: 3, title: '卡片 3' }
])
const onChange = (e) => {
console.log('当前项:', e.current, e.item)
}
const onSwipe = (e) => {
console.log('划出方向:', e.direction, '卡片:', e.item)
}
const onCardClick = (e) => {
console.log('点击卡片:', e.item)
}
const onEnd = (e) => {
console.log('全部滑完,共', e.total, '张')
}
const swipe = (dir) => stackRef.value?.swipe(dir)
const reset = () => stackRef.value?.reset()
</script>
<style scoped>
.page {
padding: 60rpx 32rpx;
}
.card-body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.card-text {
font-size: 38rpx;
font-weight: bold;
color: #ffffff;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.4);
}
.actions {
display: flex;
gap: 16rpx;
margin-top: 80rpx;
}
</style>
API
Props 属性
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
list |
Array | [] |
是 | 数据源列表,数组项为卡片数据对象 |
width |
String | '680rpx' |
否 | 卡片宽度,支持任意 CSS 尺寸 |
height |
String | '860rpx' |
否 | 卡片高度,支持任意 CSS 尺寸 |
borderRadius |
String | '32rpx' |
否 | 卡片圆角 |
shadow |
String | '0 16rpx 48rpx rgba(0, 0, 0, 0.12)' |
否 | 卡片阴影 |
imageKey |
String | 'image' |
否 | 数据项中图片字段的属性名(用于读取卡片底图) |
imageMode |
String | 'aspectFill' |
否 | 图片裁剪缩放模式,同 uni-app image 组件 mode |
bgKey |
String | 'bgColor' |
否 | 数据项中背景色字段的属性名 |
visibleCount |
Number | 3 |
否 | 可见层数,取值范围 1 ~ 5 |
offsetY |
Number | 36 |
否 | 垂直偏移步长(rpx),正数向下、负数向上、0 不位移 |
offsetX |
Number | 0 |
否 | 水平偏移步长(rpx),正数向右、负数向左、0 不位移 |
scaleStep |
Number | 0.05 |
否 | 缩放步长,正数逐层缩小、负数逐层放大、0 等大 |
rotateStep |
Number | 0 |
否 | 层叠错落旋转步长(deg),正数顺时针、负数逆时针 |
transformOrigin |
String | 'center center' |
否 | 缩放 / 旋转基准中心点,如 'center bottom' |
fadeStep |
Number | 0 |
否 | 层级透明度衰减步长,取值 0 ~ 1,越大后层越透明 |
duration |
Number | 300 |
否 | 动画过渡耗时(ms) |
timingFunction |
String | 'cubic-bezier(0.25, 1, 0.5, 1)' |
否 | 缓动动画曲线,可传任意 CSS 过渡函数 |
threshold |
Number | 80 |
否 | 判定滑出卡片的物理像素距离(px) |
loop |
Boolean | true |
否 | 是否无限循环滑动,false 时滑完触发 end 事件 |
disabled |
Boolean | false |
否 | 是否禁用滑动交互与点击(true 时锁定卡片) |
Events 事件
| 事件名 | 触发时机 | 回调参数 |
|---|---|---|
change |
当前卡片切换(含编程式 swipe()) |
{ current, item, direction } — 当前项索引、当前项数据、划出方向 'left' / 'right' |
swipe |
卡片划出(手势或编程式) | { direction, item, index } — 划出方向、划出卡片数据、在原始列表中的索引 |
cardClick |
点击当前卡片(位移小于 5px 视为点击) | { item, index } — 卡片数据、在原始列表中的索引 |
end |
非循环模式下全部卡片滑完 | { total } — 卡片总数 |
Slots 插槽
默认作用域插槽,用于完全自定义卡片内容,插槽容器铺满整张卡片:
| 插槽参数 | 类型 | 说明 |
|---|---|---|
item |
Object | 当前卡片数据 |
index |
Number | 当前卡片数据在原始列表中的索引(取模回绕后的值) |
isCurrent |
Boolean | 是否为当前最上层卡片 |
isNext |
Boolean | 是否为下一张即将切换的卡片 |
absoluteIndex |
Number | 卡片在渲染队列中的绝对索引(内部用) |
dragRatio |
Number | 当前卡片拖拽进度 0 ~ 1(仅当前卡片实时更新) |
dragDirection |
String | 当前拖拽方向:'left' / 'right' / 'none' |
实例方法
通过 ref 获取组件实例后调用:
| 方法 | 参数 | 说明 |
|---|---|---|
swipe(direction) |
direction?: 'left' \| 'right',默认 'right' |
编程式触发卡片划出动画,会同步触发 swipe / change / end 事件 |
reset() |
无 | 重置卡片索引与拖拽位移状态,回到第一张卡片 |
数据项字段与插槽叠加
组件通过 imageKey 与 bgKey 从数据项读取底图与背景色,并在其上层渲染默认插槽内容。图片/背景色作为卡片底层背景,插槽作为上层内容,二者可同时存在、互不冲突:
// 图片背景 + 插槽文字
{ id: 1, title: '图片卡', image: 'https://xxx/1.jpg' }
// 纯色背景 + 插槽内容
{ id: 2, title: '纯色卡', bgColor: '#66ccff' }
// 不设置背景:透明卡片,仅使用自定义插槽
{ id: 3, title: '自定义卡' }
常见布局推荐参数
组件本身不内置任何预设布局,以下参数组合来自示例工程的实践,可直接复用:
| 布局效果 | 参数组合 |
|---|---|
| 经典底部堆叠 | offsetY=36, offsetX=0, rotateStep=0 |
| 顶部展开 | offsetY=-36, offsetX=0, rotateStep=0 |
| 右侧展开 | offsetY=0, offsetX=36, rotateStep=0 |
| 斜向错落 | offsetY=24, offsetX=24, rotateStep=3 |
| 居中重叠 | offsetY=0, offsetX=0, rotateStep=0 |
| 扇形旋转 | offsetY=0, offsetX=0, rotateStep=6 |
注意事项
- 版本要求:本组件源码使用 Vue3
<script setup>语法,推荐用于 uni-app Vue3 项目;HBuilderX 需 3.1.0+(与package.json中engines.HBuilderX一致)。如需在 Vue2 中使用,需自行转换为 Options API 写法。 - 容器尺寸:组件默认
margin: 0 auto居中,尺寸由width/height控制,请为容器预留足够空间。 - 触摸冲突:组件内部已设置
touch-action: none,若外层页面需要纵向滚动,请将组件放置在独立容器中,并合理控制卡片拖拽方向。 - 数据更新:动态增删
list数据时,建议在变更后调用reset()使卡片状态归位。 - 图片字段:若数据项中无图片字段(或图片为空),组件自动跳过图片渲染,不影响插槽内容。
- 点击事件:需要区分「轻触点击」与「拖拽滑动」时,建议监听
cardClick事件;插槽内自定义元素仍可正常绑定点击事件,但需注意与拖拽手势的冲突。
更新日志
详见 changelog.md。

收藏人数:
https://github.com/Jonathan-614/uniapp-plugin-stack-sample
下载插件并导入HBuilderX
下载示例项目ZIP
赞赏(0)
下载 8
赞赏 0
下载 12551500
赞赏 1948
赞赏
京公网安备:11010802035340号