diff --git a/src/pages.json b/src/pages.json
index d85cf603..3d78faa0 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -36,6 +36,15 @@
}
}
},
+ {
+ "path": "pages/welcome/index",
+ "style": {
+ "navigationBarTitleText": "欢迎",
+ "app-plus": {
+ "titleNView": false
+ }
+ }
+ },
{
"path": "pages/study/index",
"style": {
diff --git a/src/pages/setting/index.vue b/src/pages/setting/index.vue
index 3ee86fc9..1b999866 100644
--- a/src/pages/setting/index.vue
+++ b/src/pages/setting/index.vue
@@ -46,7 +46,10 @@ const sexOptions = [
{ value: 'Y', label: '男' },
{ value: 'M', label: '女' }
];
-const cellCLick = (value) => {};
+const cellCLick = (value) => {
+ sexOptions.length = 0;
+ console.log(sexOptions,'sisisis');
+};
const sexChange = (e) => {
console.log(e);
console.log(sexOptions[e.detail.value].value, 'sexOptions[e.detail.value].value');
diff --git a/src/pages/welcome/index.vue b/src/pages/welcome/index.vue
new file mode 100644
index 00000000..f1a42dcc
--- /dev/null
+++ b/src/pages/welcome/index.vue
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+ {{ textList[indexNow].title }}
+ {{ textList[indexNow].tips }}
+
+
+
+
+
diff --git a/src/pagesOther.json b/src/pagesOther.json
index bda555b2..a61cebed 100644
--- a/src/pagesOther.json
+++ b/src/pagesOther.json
@@ -1,41 +1,50 @@
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
- {
- "path": "pages/index/index",
- "style": {
- "navigationBarTitleText": "首页",
- "app-plus": {
- "titleNView": false
+ {
+ "path": "pages/index/index",
+ "style": {
+ "navigationBarTitleText": "首页",
+ "app-plus": {
+ "titleNView": false
+ }
+ }
+ },
+ {
+ "path": "pages/courseDetail/index",
+ "style": {
+ "navigationBarTitleText": "课程详情",
+ "app-plus": {
+ "titleNView": false
+ }
+ }
+ },
+ {
+ "path": "pages/courseDetail/submit",
+ "style": {
+ "navigationBarTitleText": "提交评价",
+ "app-plus": {
+ "titleNView": false
+ }
+ }
+ },
+ {
+ "path": "pages/setting/index",
+ "style": {
+ "navigationBarTitleText": "设置",
+ "app-plus": {
+ "titleNView": false
+ }
+ }
+ },
+ {
+ "path": "pages/welcome/index",
+ "style": {
+ "navigationBarTitleText": "欢迎",
+ "app-plus": {
+ "titleNView": false
+ }
}
}
- },
- {
- "path": "pages/courseDetail/index",
- "style": {
- "navigationBarTitleText": "课程详情",
- "app-plus": {
- "titleNView": false
- }
- }
- },
- {
- "path": "pages/courseDetail/submit",
- "style": {
- "navigationBarTitleText": "提交评价",
- "app-plus": {
- "titleNView": false
- }
- }
- },
- {
- "path": "pages/setting/index",
- "style": {
- "navigationBarTitleText": "设置",
- "app-plus": {
- "titleNView": false
- }
- }
- }
],
"tabBar": {
"list": [{
diff --git a/src/static/images/welcome/01.png b/src/static/images/welcome/01.png
new file mode 100644
index 00000000..6ac692ab
Binary files /dev/null and b/src/static/images/welcome/01.png differ
diff --git a/src/static/images/welcome/02.png b/src/static/images/welcome/02.png
new file mode 100644
index 00000000..e1887551
Binary files /dev/null and b/src/static/images/welcome/02.png differ
diff --git a/src/static/images/welcome/03.png b/src/static/images/welcome/03.png
new file mode 100644
index 00000000..354fb941
Binary files /dev/null and b/src/static/images/welcome/03.png differ
diff --git a/src/uni_modules/uv-swipe-action/changelog.md b/src/uni_modules/uv-swipe-action/changelog.md
new file mode 100644
index 00000000..508543cd
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/changelog.md
@@ -0,0 +1,11 @@
+## 1.0.4(2023-10-13)
+1. 优化
+## 1.0.3(2023-10-13)
+1. unmounted兼容vue3
+## 1.0.2(2023-05-27)
+1. 不支持抖音小程序说明
+## 1.0.1(2023-05-16)
+1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
+2. 优化部分功能
+## 1.0.0(2023-05-10)
+uv-swipe-action 滑动单元格
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs
new file mode 100644
index 00000000..3d62784a
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs
@@ -0,0 +1,256 @@
+/**
+ * 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台
+ * wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性
+ */
+
+// 开始触摸
+function touchstart(event, ownerInstance) {
+ // 触发事件的组件的ComponentDescriptor实例
+ var instance = event.instance
+ // wxs内的局部变量快照,此快照是属于整个组件的,在touchstart和touchmove事件中都能获取到相同的结果
+ var state = instance.getState()
+ if (state.disable) return
+ var touches = event.touches
+ // 如果进行的是多指触控,不允许进行操作
+ if (touches && touches.length > 1) return
+ // 标识当前为滑动中状态
+ state.moving = true
+ // 记录触摸开始点的坐标值
+ state.startX = touches[0].pageX
+ state.startY = touches[0].pageY
+}
+
+// 触摸滑动
+function touchmove(event, ownerInstance) {
+ // 触发事件的组件的ComponentDescriptor实例
+ var instance = event.instance
+ // wxs内的局部变量快照
+ var state = instance.getState()
+ if (state.disabled || !state.moving) return
+
+ var touches = event.touches
+ var pageX = touches[0].pageX
+ var pageY = touches[0].pageY
+ var moveX = pageX - state.startX
+ var moveY = pageY - state.startY
+ var buttonsWidth = state.buttonsWidth
+
+ // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动
+ if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {
+ event.preventDefault()
+ event.stopPropagation()
+ }
+ // 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格
+ if (Math.abs(moveX) < Math.abs(moveY)) return
+
+ // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断
+ // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是
+ // 在超出后,设置为0
+ if (state.status === 'open') {
+ // 在开启状态下,向左滑动,需忽略
+ if (moveX < 0) moveX = 0
+ // 想要收起菜单,最大能移动的距离为按钮的总宽度
+ if (moveX > buttonsWidth) moveX = buttonsWidth
+ // 如果是已经打开了的状态,向左滑动时,移动收起菜单
+ moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)
+ } else {
+ // 关闭状态下,右滑动需忽略
+ if (moveX > 0) moveX = 0
+ // 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数
+ if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
+ // 只要是在滑过程中,就不断移动菜单的内容部分,从而使隐藏的菜单显示出来
+ moveSwipeAction(moveX, instance, ownerInstance)
+ }
+}
+
+// 触摸结束
+function touchend(event, ownerInstance) {
+ // 触发事件的组件的ComponentDescriptor实例
+ var instance = event.instance
+ // wxs内的局部变量快照
+ var state = instance.getState()
+ if (!state.moving || state.disabled) return
+ var touches = event.changedTouches ? event.changedTouches[0] : {}
+ var pageX = touches.pageX
+ var pageY = touches.pageY
+ var moveX = pageX - state.startX
+ if (state.status === 'open') {
+ // 在展开的状态下,继续左滑,无需操作
+ if (moveX < 0) return
+ // 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑
+ if (moveX === 0) {
+ return closeSwipeAction(instance, ownerInstance)
+ }
+ // 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态
+ if (Math.abs(moveX) < state.threshold) {
+ openSwipeAction(instance, ownerInstance)
+ } else {
+ // 如果滑动距离大于阈值,则执行收起逻辑
+ closeSwipeAction(instance, ownerInstance)
+ }
+ } else {
+ // 在关闭的状态下,右滑,无需操作
+ if (moveX > 0) return
+ // 理由同上
+ if (Math.abs(moveX) < state.threshold) {
+ closeSwipeAction(instance, ownerInstance)
+ } else {
+ openSwipeAction(instance, ownerInstance)
+ }
+ }
+}
+
+// 获取过渡时间
+function getDuration(value) {
+ if (value.toString().indexOf('s') >= 0) return value
+ return value > 30 ? value + 'ms' : value + 's'
+}
+
+// 滑动结束时判断滑动的方向
+function getMoveDirection(instance, ownerInstance) {
+ var state = instance.getState()
+}
+
+// 移动滑动选择器内容区域,同时显示出其隐藏的菜单
+function moveSwipeAction(moveX, instance, ownerInstance) {
+ var state = instance.getState()
+ // 获取所有按钮的实例,需要通过它去设置按钮的位移
+ var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
+ var len = buttons.length
+ var previewButtonsMoveX = 0
+
+ // 设置菜单内容部分的偏移
+ instance.requestAnimationFrame(function() {
+ instance.setStyle({
+ // 设置translateX的值
+ 'transition': 'none',
+ transform: 'translateX(' + moveX + 'px)',
+ '-webkit-transform': 'translateX(' + moveX + 'px)'
+ })
+ // 折叠按钮动画
+ for (var i = len - 1; i >= 0; i--) {
+ // 通过比例,得出元素自身该移动的距离
+ var translateX = state.buttons[i].width / state.buttonsWidth * moveX
+ // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和
+ var realTranslateX = translateX + previewButtonsMoveX
+ buttons[i].setStyle({
+ // 在移动期间,不能使用过渡效果,否则会造成卡顿,本质原因是每次移动一点,就要花一定时间去过渡这个过程
+ 'transition': 'none',
+ 'transform': 'translateX(' + realTranslateX + 'px)',
+ '-webkit-transform': 'translateX(' + realTranslateX + 'px)'
+ })
+ // 记录本按钮之前的所有按钮的移动距离之和
+ previewButtonsMoveX += translateX
+ }
+ })
+}
+
+// 一次性展开滑动菜单
+function openSwipeAction(instance, ownerInstance) {
+ var state = instance.getState()
+ // 获取所有按钮的实例,需要通过它去设置按钮的位移
+ var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
+ var len = buttons.length
+ // 处理duration单位问题
+ const duration = getDuration(state.duration)
+ // 展开过程中,是向左移动,所以X的偏移应该为负值
+ var buttonsWidth = -state.buttonsWidth
+ var previewButtonsMoveX = 0
+ instance.requestAnimationFrame(function() {
+ // 设置菜单主体内容
+ instance.setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(' + buttonsWidth + 'px)',
+ '-webkit-transform': 'translateX(' + buttonsWidth + 'px)',
+ })
+ // 设置各个隐藏的按钮为展开的状态
+ for (var i = len - 1; i >= 0; i--) {
+ // 通过比例,得出元素自身该移动的距离
+ var translateX = state.buttons[i].width / state.buttonsWidth * buttonsWidth
+ // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和
+ var realTranslateX = translateX + previewButtonsMoveX
+ buttons[i].setStyle({
+ // 在移动期间,需要加上动画效果
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(' + realTranslateX + 'px)',
+ '-webkit-transform': 'translateX(' + realTranslateX + 'px)'
+ })
+ // 记录本按钮之前的所有按钮的移动距离之和
+ previewButtonsMoveX += translateX
+ }
+ })
+ setStatus('open', instance)
+}
+
+// 标记菜单的当前状态,open-已经打开,close-已经关闭
+function setStatus(status, instance) {
+ var state = instance.getState()
+ state.status = status
+}
+
+// 一次性收起滑动菜单
+function closeSwipeAction(instance, ownerInstance) {
+ var state = instance.getState()
+ // 获取所有按钮的实例,需要通过它去设置按钮的位移
+ var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
+ var len = buttons.length
+ // 处理duration单位问题
+ const duration = getDuration(state.duration)
+ instance.requestAnimationFrame(function() {
+ // 设置菜单主体内容
+ instance.setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(0px)',
+ '-webkit-transform': 'translateX(0px)'
+ })
+ // 设置各个隐藏的按钮为收起的状态
+ for (var i = len - 1; i >= 0; i--) {
+ buttons[i].setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(0px)',
+ '-webkit-transform': 'translateX(0px)'
+ })
+ }
+ })
+ setStatus('close', instance)
+}
+
+// show的状态发生变化
+function showChange(newValue, oldValue, ownerInstance, instance) {
+ var state = instance.getState()
+ if (state.disabled) return
+ // 打开或关闭单元格
+ if (newValue) {
+ openSwipeAction(instance, ownerInstance)
+ } else {
+ closeSwipeAction(instance, ownerInstance)
+ }
+}
+
+// 菜单尺寸发生变化
+function sizeChange(newValue, oldValue, ownerInstance, instance) {
+ // wxs内的局部变量快照
+ var state = instance.getState()
+ state.disabled = newValue.disabled
+ state.duration = newValue.duration
+ state.show = newValue.show
+ state.threshold = newValue.threshold
+ state.buttons = newValue.buttons
+
+ var len = state.buttons.length
+ if (len) {
+ var buttonsWidth = 0
+ var buttons = newValue.buttons
+ for (var i = 0; i < len; i++) {
+ buttonsWidth += buttons[i].width
+ }
+ }
+ state.buttonsWidth = buttonsWidth
+}
+
+module.exports = {
+ touchstart: touchstart,
+ touchmove: touchmove,
+ touchend: touchend,
+ sizeChange: sizeChange
+}
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs
new file mode 100644
index 00000000..16add565
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs
@@ -0,0 +1,225 @@
+/**
+ * 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台
+ * wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性
+ */
+
+// 开始触摸
+function touchstart(event, ownerInstance) {
+ // 触发事件的组件的ComponentDescriptor实例
+ var instance = event.instance
+ // wxs内的局部变量快照,此快照是属于整个组件的,在touchstart和touchmove事件中都能获取到相同的结果
+ var state = instance.getState()
+ if (state.disabled) return
+ var touches = event.touches
+ // 如果进行的是多指触控,不允许进行操作
+ if (touches && touches.length > 1) return
+ // 标识当前为滑动中状态
+ state.moving = true
+ // 记录触摸开始点的坐标值
+ state.startX = touches[0].pageX
+ state.startY = touches[0].pageY
+
+ ownerInstance.callMethod('closeOther')
+}
+
+// 触摸滑动
+function touchmove(event, ownerInstance) {
+ // 触发事件的组件的ComponentDescriptor实例
+ var instance = event.instance
+ // wxs内的局部变量快照
+ var state = instance.getState()
+ if (state.disabled || !state.moving) return
+ var touches = event.touches
+ var pageX = touches[0].pageX
+ var pageY = touches[0].pageY
+ var moveX = pageX - state.startX
+ var moveY = pageY - state.startY
+ var buttonsWidth = state.buttonsWidth
+
+ // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动
+ if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {
+ event.preventDefault && event.preventDefault()
+ event.stopPropagation && event.stopPropagation()
+ }
+ // 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格
+ if (Math.abs(moveX) < Math.abs(moveY)) return
+
+ // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断
+ // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是
+ // 在超出后,设置为0
+ if (state.status === 'open') {
+ // 在开启状态下,向左滑动,需忽略
+ if (moveX < 0) moveX = 0
+ // 想要收起菜单,最大能移动的距离为按钮的总宽度
+ if (moveX > buttonsWidth) moveX = buttonsWidth
+ // 如果是已经打开了的状态,向左滑动时,移动收起菜单
+ moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)
+ } else {
+ // 关闭状态下,右滑动需忽略
+ if (moveX > 0) moveX = 0
+ // 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数
+ if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
+ // 只要是在滑过程中,就不断移动单元格内容部分,从而使隐藏的菜单显示出来
+ moveSwipeAction(moveX, instance, ownerInstance)
+ }
+}
+
+// 触摸结束
+function touchend(event, ownerInstance) {
+ // 触发事件的组件的ComponentDescriptor实例
+ var instance = event.instance
+ // wxs内的局部变量快照
+ var state = instance.getState()
+ if (!state.moving || state.disabled) return
+ var touches = event.changedTouches ? event.changedTouches[0] : {}
+ var pageX = touches.pageX
+ var pageY = touches.pageY
+ var moveX = pageX - state.startX
+ if (state.status === 'open') {
+ // 在展开的状态下,继续左滑,无需操作
+ if (moveX < 0) return
+ // 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑
+ if (moveX === 0) {
+ return closeSwipeAction(instance, ownerInstance)
+ }
+ // 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态
+ if (Math.abs(moveX) < state.threshold) {
+ openSwipeAction(instance, ownerInstance)
+ } else {
+ // 如果滑动距离大于阈值,则执行收起逻辑
+ closeSwipeAction(instance, ownerInstance)
+ }
+ } else {
+ // 在关闭的状态下,右滑,无需操作
+ if (moveX > 0) return
+ // 理由同上
+ if (Math.abs(moveX) < state.threshold) {
+ closeSwipeAction(instance, ownerInstance)
+ } else {
+ openSwipeAction(instance, ownerInstance)
+ }
+ }
+}
+
+// 获取过渡时间
+function getDuration(value) {
+ if (value.toString().indexOf('s') >= 0) return value
+ return value > 30 ? value + 'ms' : value + 's'
+}
+
+// 滑动结束时判断滑动的方向
+function getMoveDirection(instance, ownerInstance) {
+ var state = instance.getState()
+}
+
+// 移动滑动选择器内容区域,同时显示出其隐藏的菜单
+function moveSwipeAction(moveX, instance, ownerInstance) {
+ var state = instance.getState()
+ // 获取所有按钮的实例,需要通过它去设置按钮的位移
+ var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
+
+ // 设置菜单内容部分的偏移
+ instance.requestAnimationFrame(function() {
+ instance.setStyle({
+ // 设置translateX的值
+ 'transition': 'none',
+ transform: 'translateX(' + moveX + 'px)',
+ '-webkit-transform': 'translateX(' + moveX + 'px)'
+ })
+ })
+}
+
+// 一次性展开滑动菜单
+function openSwipeAction(instance, ownerInstance) {
+ var state = instance.getState()
+ // 获取所有按钮的实例,需要通过它去设置按钮的位移
+ var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
+ // 处理duration单位问题
+ var duration = getDuration(state.duration)
+ // 展开过程中,是向左移动,所以X的偏移应该为负值
+ var buttonsWidth = -state.buttonsWidth
+ instance.requestAnimationFrame(function() {
+ // 设置菜单主体内容
+ instance.setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(' + buttonsWidth + 'px)',
+ '-webkit-transform': 'translateX(' + buttonsWidth + 'px)',
+ })
+ })
+ setStatus('open', instance, ownerInstance)
+}
+
+// 标记菜单的当前状态,open-已经打开,close-已经关闭
+function setStatus(status, instance, ownerInstance) {
+ var state = instance.getState()
+ state.status = status
+ ownerInstance.callMethod('setState', status)
+}
+
+// 一次性收起滑动菜单
+function closeSwipeAction(instance, ownerInstance) {
+ var state = instance.getState()
+ // 获取所有按钮的实例,需要通过它去设置按钮的位移
+ var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button')
+ var len = buttons.length
+ // 处理duration单位问题
+ var duration = getDuration(state.duration)
+ instance.requestAnimationFrame(function() {
+ // 设置菜单主体内容
+ instance.setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(0px)',
+ '-webkit-transform': 'translateX(0px)'
+ })
+ // 设置各个隐藏的按钮为收起的状态
+ for (var i = len - 1; i >= 0; i--) {
+ buttons[i].setStyle({
+ 'transition': 'transform ' + duration,
+ 'transform': 'translateX(0px)',
+ '-webkit-transform': 'translateX(0px)'
+ })
+ }
+ })
+ setStatus('close', instance, ownerInstance)
+}
+
+// status的状态发生变化
+function statusChange(newValue, oldValue, ownerInstance, instance) {
+ var state = instance.getState()
+ if (state.disabled) return
+ // 打开或关闭单元格
+ if (newValue === 'close' && state.status === 'open') {
+ closeSwipeAction(instance, ownerInstance)
+ } else if(newValue === 'open' && state.status === 'close') {
+ openSwipeAction(instance, ownerInstance)
+ }
+}
+
+// 菜单尺寸发生变化
+function sizeChange(newValue, oldValue, ownerInstance, instance) {
+ // wxs内的局部变量快照
+ var state = instance.getState()
+ state.disabled = newValue.disabled
+ state.duration = newValue.duration
+ state.show = newValue.show
+ state.threshold = newValue.threshold
+ state.buttons = newValue.buttons
+
+ if (state.buttons) {
+ var len = state.buttons.length
+ var buttonsWidth = 0
+ var buttons = newValue.buttons
+ for (var i = 0; i < len; i++) {
+ buttonsWidth += buttons[i].width
+ }
+ }
+ state.buttonsWidth = buttonsWidth
+}
+
+module.exports = {
+ touchstart: touchstart,
+ touchmove: touchmove,
+ touchend: touchend,
+ sizeChange: sizeChange,
+ statusChange: statusChange
+}
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js
new file mode 100644
index 00000000..da259e87
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js
@@ -0,0 +1,264 @@
+// nvue操作dom的库,用于获取dom的尺寸信息
+const dom = uni.requireNativePlugin('dom')
+// nvue中用于操作元素动画的库,类似于uni.animation,只不过uni.animation不能用于nvue
+const animation = uni.requireNativePlugin('animation')
+import { sleep } from '@/uni_modules/uv-ui-tools/libs/function/index.js'
+export default {
+ data() {
+ return {
+ // 是否滑动中
+ moving: false,
+ // 状态,open-打开状态,close-关闭状态
+ status: 'close',
+ // 开始触摸点的X和Y轴坐标
+ startX: 0,
+ startY: 0,
+ // 所有隐藏按钮的尺寸信息数组
+ buttons: [],
+ // 所有按钮的总宽度
+ buttonsWidth: 0,
+ // 记录上一次移动的位置值
+ moveX: 0,
+ // 记录上一次滑动的位置,用于前后两次做对比,如果移动的距离小于某一阈值,则认为前后之间没有移动,为了解决可能存在的通信阻塞问题
+ lastX: 0
+ }
+ },
+ computed: {
+ // 获取过渡时间
+ getDuratin() {
+ let duration = String(this.duration)
+ // 如果ms为单位,返回ms的数值部分
+ if (duration.indexOf('ms') >= 0) return parseInt(duration)
+ // 如果s为单位,为了得到ms的数值,需要乘以1000
+ if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000
+ // 如果值传了数值,且小于30,认为是s单位
+ duration = Number(duration)
+ return duration < 30 ? duration * 1000 : duration
+ }
+ },
+ watch: {
+ show: {
+ immediate: true,
+ handler(n) {
+
+ }
+ }
+ },
+ mounted() {
+ sleep(20).then(() => {
+ this.queryRect()
+ })
+ },
+ methods: {
+ close() {
+ this.closeSwipeAction()
+ },
+ // 触摸单元格
+ touchstart(event) {
+ if (this.disabled) return
+ this.closeOther()
+ const { touches } = event
+ // 记录触摸开始点的坐标值
+ this.startX = touches[0].pageX
+ this.startY = touches[0].pageY
+ },
+ // // 触摸滑动
+ touchmove(event) {
+ if (this.disabled) return
+ const { touches } = event
+ const { pageX } = touches[0]
+ const { pageY } = touches[0]
+ let moveX = pageX - this.startX
+ const moveY = pageY - this.startY
+ const { buttonsWidth } = this
+ const len = this.buttons.length
+
+ // 判断前后两次的移动距离,如果小于一定值,则不进行移动处理
+ if (Math.abs(pageX - this.lastX) < 0.3) return
+ this.lastX = pageX
+
+ // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动
+ if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > this.threshold) {
+ event.stopPropagation()
+ }
+ // 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格
+ if (Math.abs(moveX) < Math.abs(moveY)) return
+
+ // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断
+ // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是
+ // 在超出后,设置为0
+ if (this.status === 'open') {
+ // 在开启状态下,向左滑动,需忽略
+ if (moveX < 0) moveX = 0
+ // 想要收起菜单,最大能移动的距离为按钮的总宽度
+ if (moveX > buttonsWidth) moveX = buttonsWidth
+ // 如果是已经打开了的状态,向左滑动时,移动收起菜单
+ this.moveSwipeAction(-buttonsWidth + moveX)
+ } else {
+ // 关闭状态下,右滑动需忽略
+ if (moveX > 0) moveX = 0
+ // 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数
+ if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
+ // 只要是在滑过程中,就不断移动菜单的内容部分,从而使隐藏的菜单显示出来
+ this.moveSwipeAction(moveX)
+ }
+ },
+ // 单元格结束触摸
+ touchend(event) {
+ if (this.disabled) return
+ const touches = event.changedTouches ? event.changedTouches[0] : {}
+ const { pageX } = touches
+ const { pageY } = touches
+ const { buttonsWidth } = this
+ this.moveX = pageX - this.startX
+ if (this.status === 'open') {
+ // 在展开的状态下,继续左滑,无需操作
+ if (this.moveX < 0) this.moveX = 0
+ if (this.moveX > buttonsWidth) this.moveX = buttonsWidth
+ // 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑
+ if (this.moveX === 0) {
+ return this.closeSwipeAction()
+ }
+ // 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态
+ if (Math.abs(this.moveX) < this.threshold) {
+ this.openSwipeAction()
+ } else {
+ // 如果滑动距离大于阈值,则执行收起逻辑
+ this.closeSwipeAction()
+ }
+ } else {
+ // 在关闭的状态下,右滑,无需操作
+ if (this.moveX >= 0) this.moveX = 0
+ if (this.moveX <= -buttonsWidth) this.moveX = -buttonsWidth
+ // 理由同上
+ if (Math.abs(this.moveX) < this.threshold) {
+ this.closeSwipeAction()
+ } else {
+ this.openSwipeAction()
+ }
+ }
+ },
+ // 移动滑动选择器内容区域,同时显示出其隐藏的菜单
+ moveSwipeAction(moveX) {
+ if (this.moving) return
+ this.moving = true
+
+ let previewButtonsMoveX = 0
+ const len = this.buttons.length
+ animation.transition(this.$refs['uv-swipe-action-item__content'].ref, {
+ styles: {
+ transform: `translateX(${moveX}px)`
+ },
+ timingFunction: 'linear'
+ }, () => {
+ this.moving = false
+ })
+ // 按钮的组的长度
+ for (let i = len - 1; i >= 0; i--) {
+ const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref
+ // 通过比例,得出元素自身该移动的距离
+ const translateX = this.buttons[i].width / this.buttonsWidth * moveX
+ // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和
+ const realTranslateX = translateX + previewButtonsMoveX
+ animation.transition(buttonRef, {
+ styles: {
+ transform: `translateX(${realTranslateX}px)`
+ },
+ duration: 0,
+ delay: 0,
+ timingFunction: 'linear'
+ }, () => {})
+ // 记录本按钮之前的所有按钮的移动距离之和
+ previewButtonsMoveX += translateX
+ }
+ },
+ // 关闭菜单
+ closeSwipeAction() {
+ if (this.status === 'close') return
+ this.moving = true
+ const { buttonsWidth } = this
+ animation.transition(this.$refs['uv-swipe-action-item__content'].ref, {
+ styles: {
+ transform: 'translateX(0px)'
+ },
+ duration: this.getDuratin,
+ timingFunction: 'ease-in-out'
+ }, () => {
+ this.status = 'close'
+ this.moving = false
+ this.closeHandler()
+ })
+ // 按钮的组的长度
+ const len = this.buttons.length
+ for (let i = len - 1; i >= 0; i--) {
+ const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref
+ // 如果不满足边界条件,返回
+ if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return
+
+ animation.transition(buttonRef, {
+ styles: {
+ transform: 'translateX(0px)'
+ },
+ duration: this.getDuratin,
+ timingFunction: 'ease-in-out'
+ }, () => {})
+ }
+ },
+ // 打开菜单
+ openSwipeAction() {
+ if (this.status === 'open') return
+ this.moving = true
+ const buttonsWidth = -this.buttonsWidth
+ let previewButtonsMoveX = 0
+ animation.transition(this.$refs['uv-swipe-action-item__content'].ref, {
+ styles: {
+ transform: `translateX(${buttonsWidth}px)`
+ },
+ duration: this.getDuratin,
+ timingFunction: 'ease-in-out'
+ }, () => {
+ this.status = 'open'
+ this.moving = false
+ this.openHandler()
+ })
+ // 按钮的组的长度
+ const len = this.buttons.length
+ for (let i = len - 1; i >= 0; i--) {
+ const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref
+ // 如果不满足边界条件,返回
+ if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return
+ // 通过比例,得出元素自身该移动的距离
+ const translateX = this.buttons[i].width / this.buttonsWidth * buttonsWidth
+ // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和
+ const realTranslateX = translateX + previewButtonsMoveX
+ animation.transition(buttonRef, {
+ styles: {
+ transform: `translateX(${realTranslateX}px)`
+ },
+ duration: this.getDuratin,
+ timingFunction: 'ease-in-out'
+ }, () => {})
+ previewButtonsMoveX += translateX
+ }
+ },
+ // 查询按钮节点信息
+ queryRect() {
+ // 历遍所有按钮数组,通过getRectByDom返回一个promise
+ const promiseAll = this.rightOptions.map((item, index) => this.getRectByDom(this.$refs[`uv-swipe-action-item__right__button-${index}`][0]))
+ // 通过promise.all方法,让所有按钮的查询结果返回一个数组的形式
+ Promise.all(promiseAll).then((sizes) => {
+ this.buttons = sizes
+ // 计算所有按钮总宽度
+ this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0)
+ })
+ },
+ // 通过nvue的dom模块,查询节点信息
+ getRectByDom(ref) {
+ return new Promise((resolve) => {
+ dom.getComponentRect(ref, (res) => {
+ resolve(res.size)
+ })
+ })
+ }
+ }
+}
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js
new file mode 100644
index 00000000..6eaf4913
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js
@@ -0,0 +1,182 @@
+// nvue操作dom的库,用于获取dom的尺寸信息
+const dom = uni.requireNativePlugin('dom');
+const bindingX = uni.requireNativePlugin('bindingx');
+const animation = uni.requireNativePlugin('animation');
+import { getDuration, getPx } from '@/uni_modules/uv-ui-tools/libs/function/index.js'
+export default {
+ data() {
+ return {
+ // 所有按钮的总宽度
+ buttonsWidth: 0,
+ // 是否正在移动中
+ moving: false
+ }
+ },
+ computed: {
+ // 获取过渡时间
+ getDuratin() {
+ let duration = String(this.duration)
+ // 如果ms为单位,返回ms的数值部分
+ if (duration.indexOf('ms') >= 0) return parseInt(duration)
+ // 如果s为单位,为了得到ms的数值,需要乘以1000
+ if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000
+ // 如果值传了数值,且小于30,认为是s单位
+ duration = Number(duration)
+ return duration < 30 ? duration * 1000 : duration
+ }
+ },
+ watch: {
+ show(n) {
+ if(n) {
+ this.moveCellByAnimation('open')
+ } else {
+ this.moveCellByAnimation('close')
+ }
+ }
+ },
+ mounted() {
+ setTimeout(()=>{
+ this.initialize()
+ },20)
+ },
+ methods: {
+ initialize() {
+ this.queryRect()
+ },
+ // 关闭单元格,用于打开一个,自动关闭其他单元格的场景
+ closeHandler() {
+ if(this.status === 'open') {
+ // 如果在打开状态下,进行点击的话,直接关闭单元格
+ return this.moveCellByAnimation('close') && this.unbindBindingX()
+ }
+ },
+ // 点击单元格
+ clickHandler() {
+ // 如果在移动中被点击,进行忽略
+ if(this.moving) return
+ // 尝试关闭其他打开的单元格
+ this.parent && this.parent.closeOther(this)
+ if(this.status === 'open') {
+ // 如果在打开状态下,进行点击的话,直接关闭单元格
+ return this.moveCellByAnimation('close') && this.unbindBindingX()
+ }
+ },
+ // 滑动单元格
+ onTouchstart(e) {
+ // 如果当前正在移动中,或者disabled状态,则返回
+ if(this.moving || this.disabled) {
+ return this.unbindBindingX()
+ }
+ if(this.status === 'open') {
+ // 如果在打开状态下,进行点击的话,直接关闭单元格
+ return this.moveCellByAnimation('close') && this.unbindBindingX()
+ }
+ // 特殊情况下,e可能不为一个对象
+ e?.stopPropagation && e.stopPropagation()
+ e?.preventDefault && e.preventDefault()
+ this.moving = true
+ // 获取元素ref
+ const content = this.getContentRef()
+ let expression = `min(max(${-this.buttonsWidth}, x), 0)`
+ // 尝试关闭其他打开的单元格
+ this.parent && this.parent.closeOther(this)
+ // 阿里为了KPI而开源的BindingX
+ this.panEvent = bindingX.bind({
+ anchor: content,
+ eventType: 'pan',
+ props: [{
+ element: content,
+ // 绑定width属性,设置其宽度值
+ property: 'transform.translateX',
+ expression
+ }]
+ }, (res) => {
+ this.moving = false
+ if (res.state === 'end' || res.state === 'exit') {
+ const deltaX = res.deltaX
+ if(deltaX <= -this.buttonsWidth || deltaX >= 0) {
+ // 如果触摸滑动的过程中,大于单元格的总宽度,或者大于0,意味着已经动过滑动达到了打开或者关闭的状态
+ // 这里直接进行状态的标记
+ this.$nextTick(() => {
+ this.status = deltaX <= -this.buttonsWidth ? 'open' : 'close'
+ })
+ } else if(Math.abs(deltaX) > getPx(this.threshold)) {
+ // 在移动大于阈值、并且小于总按钮宽度时,进行自动打开或者关闭
+ // 移动距离大于0时,意味着需要关闭状态
+ if(Math.abs(deltaX) < this.buttonsWidth) {
+ this.moveCellByAnimation(deltaX > 0 ? 'close' : 'open')
+ }
+ } else {
+ // 在小于阈值时,进行关闭操作(如果在打开状态下,将不会执行bindingX)
+ this.moveCellByAnimation('close')
+ }
+ }
+ })
+ },
+ // 释放bindingX
+ unbindBindingX() {
+ // 释放上一次的资源
+ if (this?.panEvent?.token != 0) {
+ bindingX.unbind({
+ token: this.panEvent?.token,
+ // pan为手势事件
+ eventType: 'pan'
+ })
+ }
+ },
+ // 查询按钮节点信息
+ queryRect() {
+ // 历遍所有按钮数组,通过getRectByDom返回一个promise
+ const promiseAll = this.options.map(async(item, index) => {
+ return await this.getRectByDom(this.$refs[`uv-swipe-action-item__right__button-${index}`][0])
+ })
+ // 通过promise.all方法,让所有按钮的查询结果返回一个数组的形式
+ Promise.all(promiseAll).then(sizes => {
+ this.buttons = sizes
+ // 计算所有按钮总宽度
+ this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0)
+ })
+ },
+ // 通过nvue的dom模块,查询节点信息
+ getRectByDom(ref) {
+ return new Promise(resolve => {
+ dom.getComponentRect(ref, res => {
+ resolve(res.size)
+ })
+ })
+ },
+ // 移动单元格到左边或者右边尽头
+ moveCellByAnimation(status = 'open') {
+ if(this.moving) return
+ // 标识当前状态
+ this.moveing = true
+ const content = this.getContentRef()
+ const x = status === 'open' ? -this.buttonsWidth : 0
+ animation.transition(content, {
+ styles: {
+ transform: `translateX(${x}px)`,
+ },
+ duration: getDuration(this.duration, false),
+ timingFunction: 'ease-in-out'
+ }, () => {
+ this.moving = false
+ this.status = status
+ this.unbindBindingX()
+ })
+ },
+ // 获取元素ref
+ getContentRef() {
+ return this.$refs['uv-swipe-action-item__content'].ref
+ }
+ },
+ // #ifdef VUE2
+ beforeDestroy() {
+ this.unbindBindingX()
+ },
+ // #endif
+ // #ifdef VUE3
+ unmounted() {
+ this.unbindBindingX()
+ }
+ // #endif
+}
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js
new file mode 100644
index 00000000..5b321e23
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js
@@ -0,0 +1,40 @@
+export default {
+ props: {
+ // 控制打开或者关闭
+ show: {
+ type: Boolean,
+ default: false
+ },
+ // 标识符,如果是v-for,可用index索引值
+ name: {
+ type: [String, Number],
+ default: ''
+ },
+ // 是否禁用
+ disabled: {
+ type: Boolean,
+ default: false
+ },
+ // 是否自动关闭其他swipe按钮组
+ autoClose: {
+ type: Boolean,
+ default: true
+ },
+ // 滑动距离阈值,只有大于此值,才被认为是要打开菜单
+ threshold: {
+ type: Number,
+ default: 20
+ },
+ // 右侧按钮内容
+ options: {
+ type: Array,
+ default: () => []
+ },
+ // 动画过渡时间,单位ms
+ duration: {
+ type: [String, Number],
+ default: 300
+ },
+ ...uni.$uv?.props?.swipeActionItem
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue
new file mode 100644
index 00000000..8fd503a4
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js
new file mode 100644
index 00000000..ee49c100
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js
@@ -0,0 +1,15 @@
+export default {
+ methods: {
+ // 关闭时执行
+ closeHandler() {
+ this.status = 'close'
+ },
+ setState(status) {
+ this.status = status
+ },
+ closeOther() {
+ // 尝试关闭其他打开的单元格
+ this.parent && this.parent.closeOther(this)
+ }
+ }
+}
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action/props.js b/src/uni_modules/uv-swipe-action/components/uv-swipe-action/props.js
new file mode 100644
index 00000000..7d06765f
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action/props.js
@@ -0,0 +1,10 @@
+export default {
+ props: {
+ // 是否自动关闭其他swipe按钮组
+ autoClose: {
+ type: Boolean,
+ default: true
+ },
+ ...uni.$uv?.props?.swipeAction
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue b/src/uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue
new file mode 100644
index 00000000..ed3e9f9c
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
diff --git a/src/uni_modules/uv-swipe-action/package.json b/src/uni_modules/uv-swipe-action/package.json
new file mode 100644
index 00000000..9eef69be
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/package.json
@@ -0,0 +1,88 @@
+{
+ "id": "uv-swipe-action",
+ "displayName": "uv-swipe-action 滑动单元格 全面兼容小程序、nvue、vue2、vue3等多端",
+ "version": "1.0.4",
+ "description": "滑动单元格组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作。",
+ "keywords": [
+ "uv-swipe-action",
+ "uvui",
+ "uv-ui",
+ "swipe-action",
+ "滑动单元格"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "type": "component-vue",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "插件不采集任何数据",
+ "permissions": "无"
+ },
+ "npmurl": ""
+ },
+ "uni_modules": {
+ "dependencies": [
+ "uv-ui-tools",
+ "uv-icon"
+ ],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y",
+ "钉钉": "u",
+ "快手": "u",
+ "飞书": "u",
+ "京东": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/uv-swipe-action/readme.md b/src/uni_modules/uv-swipe-action/readme.md
new file mode 100644
index 00000000..31806966
--- /dev/null
+++ b/src/uni_modules/uv-swipe-action/readme.md
@@ -0,0 +1,11 @@
+## SwipeAction 滑动单元格
+
+> **组件名:uv-swipe-action**
+
+该组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作。
+
+### 查看文档
+
+### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
+
+#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui、官方QQ群
diff --git a/src/uni_modules/uv-swiper/changelog.md b/src/uni_modules/uv-swiper/changelog.md
new file mode 100644
index 00000000..30f26c63
--- /dev/null
+++ b/src/uni_modules/uv-swiper/changelog.md
@@ -0,0 +1,16 @@
+## 1.0.6(2023-12-20)
+1. 优化
+## 1.0.5(2023-08-24)
+1. 修复标题文字过多未隐藏掉的BUG
+## 1.0.4(2023-07-24)
+1. 增加 滑动方向是否为纵向 属性vertical
+## 1.0.3(2023-06-27)
+1. 增加titleStyle属性,方便修改标题样式
+2. 标题上去掉是否是图片的判断,避免无后缀的图片不显示
+## 1.0.2(2023-06-01)
+1. 修复点击触发两次事件的BUG
+## 1.0.1(2023-05-16)
+1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
+2. 优化部分功能
+## 1.0.0(2023-05-10)
+uv-swiper 轮播图,走马灯
diff --git a/src/uni_modules/uv-swiper/components/uv-swiper-indicator/props.js b/src/uni_modules/uv-swiper/components/uv-swiper-indicator/props.js
new file mode 100644
index 00000000..8f305a0b
--- /dev/null
+++ b/src/uni_modules/uv-swiper/components/uv-swiper-indicator/props.js
@@ -0,0 +1,30 @@
+export default {
+ props: {
+ // 轮播的长度
+ length: {
+ type: [String, Number],
+ default: 0
+ },
+ // 当前处于活动状态的轮播的索引
+ current: {
+ type: [String, Number],
+ default: 0
+ },
+ // 指示器非激活颜色
+ indicatorActiveColor: {
+ type: String,
+ default: ''
+ },
+ // 指示器的激活颜色
+ indicatorInactiveColor: {
+ type: String,
+ default: ''
+ },
+ // 指示器模式,line-线型,dot-点型
+ indicatorMode: {
+ type: String,
+ default: ''
+ },
+ ...uni.$uv?.props?.swiperIndicator
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/uv-swiper/components/uv-swiper-indicator/uv-swiper-indicator.vue b/src/uni_modules/uv-swiper/components/uv-swiper-indicator/uv-swiper-indicator.vue
new file mode 100644
index 00000000..b326f437
--- /dev/null
+++ b/src/uni_modules/uv-swiper/components/uv-swiper-indicator/uv-swiper-indicator.vue
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/uni_modules/uv-swiper/components/uv-swiper/props.js b/src/uni_modules/uv-swiper/components/uv-swiper/props.js
new file mode 100644
index 00000000..66e47876
--- /dev/null
+++ b/src/uni_modules/uv-swiper/components/uv-swiper/props.js
@@ -0,0 +1,136 @@
+export default {
+ props: {
+ // 列表数组,元素可为字符串,如为对象可通过keyName指定目标属性名
+ list: {
+ type: Array,
+ default: () => []
+ },
+ // 是否显示面板指示器
+ indicator: {
+ type: Boolean,
+ default: false
+ },
+ // 指示器非激活颜色
+ indicatorActiveColor: {
+ type: String,
+ default: '#fff'
+ },
+ // 指示器的激活颜色
+ indicatorInactiveColor: {
+ type: String,
+ default: 'rgba(255, 255, 255, 0.35)'
+ },
+ // 指示器样式,可通过bottom,left,right进行定位
+ indicatorStyle: {
+ type: [String, Object],
+ default: ''
+ },
+ // 指示器模式,line-线型,dot-点型
+ indicatorMode: {
+ type: String,
+ default: 'line'
+ },
+ // 是否自动切换
+ autoplay: {
+ type: Boolean,
+ default: true
+ },
+ // 当前所在滑块的 index
+ current: {
+ type: [String, Number],
+ default: 0
+ },
+ // 当前所在滑块的 item-id ,不能与 current 被同时指定
+ currentItemId: {
+ type: String,
+ default: ''
+ },
+ // 滑块自动切换时间间隔
+ interval: {
+ type: [String, Number],
+ default: 3000
+ },
+ // 滑块切换过程所需时间
+ duration: {
+ type: [String, Number],
+ default: 300
+ },
+ // 播放到末尾后是否重新回到开头
+ circular: {
+ type: Boolean,
+ default: false
+ },
+ // 滑动方向是否为纵向
+ vertical: {
+ type: Boolean,
+ default: false
+ },
+ // 前边距,可用于露出前一项的一小部分,nvue和支付宝不支持
+ previousMargin: {
+ type: [String, Number],
+ default: 0
+ },
+ // 后边距,可用于露出后一项的一小部分,nvue和支付宝不支持
+ nextMargin: {
+ type: [String, Number],
+ default: 0
+ },
+ // 当开启时,会根据滑动速度,连续滑动多屏,支付宝不支持
+ acceleration: {
+ type: Boolean,
+ default: false
+ },
+ // 同时显示的滑块数量,nvue、支付宝小程序不支持
+ displayMultipleItems: {
+ type: Number,
+ default: 1
+ },
+ // 指定swiper切换缓动动画类型,有效值:default、linear、easeInCubic、easeOutCubic、easeInOutCubic
+ // 只对微信小程序有效
+ easingFunction: {
+ type: String,
+ default: 'default'
+ },
+ // list数组中指定对象的目标属性名
+ keyName: {
+ type: String,
+ default: 'url'
+ },
+ // 图片的裁剪模式
+ imgMode: {
+ type: String,
+ default: 'aspectFill'
+ },
+ // 组件高度
+ height: {
+ type: [String, Number],
+ default: 130
+ },
+ // 背景颜色
+ bgColor: {
+ type: String,
+ default: '#f3f4f6'
+ },
+ // 组件圆角,数值或带单位的字符串
+ radius: {
+ type: [String, Number],
+ default: 4
+ },
+ // 是否加载中
+ loading: {
+ type: Boolean,
+ default: false
+ },
+ // 是否显示标题,要求数组对象中有title属性
+ showTitle: {
+ type: Boolean,
+ default: false
+ },
+ // 显示的标题样式
+ titleStyle: {
+ type: [Object, String],
+ default: ''
+ },
+ ...uni.$uv?.props?.swiper
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/uv-swiper/components/uv-swiper/uv-swiper.vue b/src/uni_modules/uv-swiper/components/uv-swiper/uv-swiper.vue
new file mode 100644
index 00000000..a5b9dfcc
--- /dev/null
+++ b/src/uni_modules/uv-swiper/components/uv-swiper/uv-swiper.vue
@@ -0,0 +1,257 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/uni_modules/uv-swiper/package.json b/src/uni_modules/uv-swiper/package.json
new file mode 100644
index 00000000..f561f105
--- /dev/null
+++ b/src/uni_modules/uv-swiper/package.json
@@ -0,0 +1,88 @@
+{
+ "id": "uv-swiper",
+ "displayName": "uv-swiper 轮播图 全面兼容vue3+2、app、h5、小程序等多端",
+ "version": "1.0.6",
+ "description": "该组件为轮播、跑马灯,支持卡片式。一般用于导航轮播,广告展示等场景,开箱即用",
+ "keywords": [
+ "swiper",
+ "uvui",
+ "uv-ui",
+ "轮播图",
+ "走马灯"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "type": "component-vue",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "插件不采集任何数据",
+ "permissions": "无"
+ },
+ "npmurl": ""
+ },
+ "uni_modules": {
+ "dependencies": [
+ "uv-ui-tools",
+ "uv-loading-icon"
+ ],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y",
+ "钉钉": "u",
+ "快手": "u",
+ "飞书": "u",
+ "京东": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/uv-swiper/readme.md b/src/uni_modules/uv-swiper/readme.md
new file mode 100644
index 00000000..cae255fe
--- /dev/null
+++ b/src/uni_modules/uv-swiper/readme.md
@@ -0,0 +1,19 @@
+## Swiper 轮播图
+
+> **组件名:uv-swiper**
+
+该组件为轮播、跑马灯,支持卡片式。一般用于导航轮播,广告展示等场景,开箱即用。
+
+# 查看文档
+
+## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP)
+
+### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
+
+
+
+
+
+
+
+#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群
\ No newline at end of file