更新记录

1.0.0(2023-12-18) 下载此版本

初次发布,遇到BUG请留言反馈


平台兼容性

Vue2 Vue3
× ×
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.99 app-uvue × × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序
× × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × × × × × × × ×

演示

组件说明

  • 支持设置长按拖动,支持单列或多列排序。
  • 组件使用了插槽,行的内容直接写在插槽里,需要注意设置触摸区域item.DRAGAREA,详情看下方示例或下载示例查看。
  • 拖动到列表上下边缘会自动滚动列表,越靠近边缘滚动越快。
  • 组件只支持每行都相等高度的列表。
  • 仅支持安卓APP,其他端未做兼容。
  • 目前UTS还没有删除UTSJSONObject属性的API,组件内部在列表中加了一些拖拽排序所需要的属性,在组件返回的数据中,把这些组价内部加的属性也一并返回回来,后续等UTS可以删除UTSJSONObject属性时,会对这些属性进行删除
  • 官方还在继续完善UTS和uniappx,组件对一些还不兼容或不支持的地方做了些兼容操作处理,官方完善问题之后,组件会紧接更新修改。
  • 第一次写TS,磕磕绊绊写完,有不规范或不顺眼的地方,请指教。

属性说明

属性名 类型 说明
list Array 必填,列表数据,数据格式请参考示例,
注意:数据非双向绑定,拖动并不会直接修改list数据,排序过的数据在confirm中获取
column number 选填,列数,默认1
listWidth number 选填,列表宽度,单位:px,默认等于屏幕宽度
listHeight number 必填,整个列表的高度
rowHeight number 选填,每一行的高度,单位:px,默认44px
longTouch boolean 选填,是否长按拖动,可选值true/false,默认false 关闭,如果是改了整行可拖拽,请开启长按拖拽,避免列表不能滚动
longTouchTime number 选填,触发长按时长,单位:ms,默认350ms
autoScroll boolean 选填,是否拖拽至边缘自动滚动列表,可选值true/false,默认true 开启
@onclick EventHandle 点击事件,返回被点击行的数据,event = {sort:被点击行的排序位置 as number,row:被点击行的数据 as UTSJSONObject}
@confirm EventHandle 拖拽结束,且行位置发生了改变,触发confirm事件,event = {sort:原排序位置 as number,moveTo:被拖动到的排序位置 as number,row:拖动行数据 as UTSJSONObject,list:整个列表拖动排序后的数据 as Array}
@change EventHandle 拖拽过程中,行位置发生交换时,触发change事件,event = {sort:原排序位置 as number,moveTo:被拖动到的排序位置 as number,row:拖动行数据 as UTSJSONObject}

插槽说明

<template  v-slot="item">
    <!-- item.data item数据 调用方法是item.data['xxx']-->
    <!-- item.DRAGAREA 请在需要触发拖拽的区域设置class为 item.DRAGAREA-->

    <!-- 如果需要整格拖拽 则所有内容写在class为item.DRAGAREA的view内-->
    <view :class="item.DRAGAREA">
        <!-- 这个view里所有元素都会触发拖拽 -->
    </view>
    <view class="xxx">
        <!-- 这个view里所有元素不会触发拖拽 -->
    </view>
</template>

内置函数说明

getDragListForSorted函数

除了在中@confirm回调里获取排序后的list,还可以主动调用getDragListForSorted获取排序后的list,数据类型为Array<UTSJSONObject>

    let tmplist:Array<UTSJSONObject> = (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).getDragListForSorted();

push,unshit,splice函数

内置了push,unshift,splice函数,组件设置ref属性,通过$refs调用,实现列表的删除插入,unshift,splice函数修改后会返回修改后的整个list。

    push(newRows: Array<UTSJSONObject>): Array<UTSJSONObject>
    unshift(newRows: Array<UTSJSONObject>): Array<UTSJSONObject>
    splice(deleteIndex: number, howmany: number, newRows: Array<UTSJSONObject>): Array<UTSJSONObject>

###注意

uts在methods中尚不支持剩余参数,也尚不支持默认参数,所以上面newRows是必填参数且是Array数组。
插入一行数据要传入数组[newRow],不传newRows也要传入个[]空数组,不然编译器会报错参数不够编译不通过。
等后续uts支持了再修改这种传参方式。

例子:

 // push单行
 let tmplistA:Array<UTSJSONObject> = (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).push([row1]);
 // unshift多行
 let tmplistB:Array<UTSJSONObject> = (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).unshift([row1,...,rowX]);
 // 从下标5开始删除1个元素 并插入X行
 let tmplistC:Array<UTSJSONObject> = (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).splice(5,1,[row1,...,rowX]);
 // 从下标5位置开始删除1个元素 并插入1行
 let tmplistD:Array<UTSJSONObject> = (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).splice(5,1,[row1]);
 // 从下标5位置开始删除1个元素 不插入行 不插入行也要传入个[]空数组
 let tmplistD:Array<UTSJSONObject> = (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).splice(5,1,[]);

完整例子:

推荐请下载示例运行查看,有示例对照注释更容易明白。

 <template>
    <view class="content">
        <HM-dragSortsUvue ref="dragSorts" :list="list" 
            :longTouch="longTouch" :column="column" 
            :rowHeight="rowHeight" :listHeight="listHeight" :listWidth="listWidth"
            @onclick="onclick" @change="change" @confirm="confirm">
            <template  v-slot="item">
                <!-- 内容  -->
                <view class="row-content"
                    :style="{'height': rowHeight.toString()+'px'}"
                >
                    <image class="row-content-icon" :src="item.data['icon']"></image>
                    <text class="text">{{item.data['name']}}</text>
                </view>
                <!-- 组件内会识别class包含item.DRAGAREA的view作为触发拖拽的区域 -->
                <!-- 如果需要做整格拖拽,可以把所有内容写进包含item.DRAGAREA的view,如果是整格拖拽,请开启长按拖拽,否则不可滑动列表 -->
                <view class="row-drag" :class="item.DRAGAREA"
                    :style="{'height': rowHeight.toString()+'px'}"
                >
                    <image class="drag-icon"  src="/static/drag.png"></image>
                </view>
            </template>
            </HM-dragSortsUvue>
    </view>
 </template>
 <script>

    export default {
        data() {
            return {

                longTouch:false as boolean,
                column:2 as number,
                // 尺寸全部为px,rpx转px可以使用 UTSAndroid.rpx2px(x)
                rowHeight:100 as number,
                listHeight:500,
                listWidth:UTSAndroid.rpx2px(750) as number,
                list:[] as Array<UTSJSONObject>,
                tmplist: [
                    {"name": "项目","icon": "/static/img/1.png",},
                    {"name": "项目","icon": "/static/img/2.png",},
                    {"name": "项目","icon": "/static/img/3.png"},
                    {"name": "项目","icon": "/static/img/4.png"},
                    {"name": "项目","icon": "/static/img/5.png"},
                    {"name": "项目","icon": "/static/img/6.png"}
                ] as Array<UTSJSONObject>
            }
        }, 
        onLoad() {
            let listdata:Array<UTSJSONObject>=[];
            // 组装测试数据
            for (let i = 0; i < 20; i++) {
                var index:number  = i%6;
                var tmp = JSON.parse(JSON.stringify(this.tmplist[index])) as UTSJSONObject;
                tmp['name'] = '项目'+i.toString();
                listdata.push(tmp); 
            } 
            this.list = listdata;
        },
        methods: {
            push(){
                (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).push([{
                        "name": "push行",
                        "icon": "/static/img/2.png"
                    }]);
            },
            unshift(){
                (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).unshift([{
                        "name": "unshift行",
                        "icon": "/static/img/2.png"
                    }]);
            },
            splice(){
                (this.$refs['dragSorts'] as HMDragSortsUvueComponentPublicInstance).splice(1,1,[{
                        "name": "splice行",
                        "icon": "/static/img/2.png"
                    }]);
            },
            onclick(e:UTSJSONObject) {
                console.log('=== onclick start ===');
                console.log("被点击排序: " , e['sort']);
                console.log("被点击行: " ,e['row']);
                console.log('=== onclick end ===');
            },
            change(e:UTSJSONObject){
                console.log('=== change start ===');
                console.log("被拖动行: " ,e['row']);
                console.log('原始下标:',e['sort']);
                console.log('移动到:',e['moveTo']);
                console.log('=== change end ===');
            },
            confirm(e:UTSJSONObject){
                console.log('=== confirm start ===');
                console.log("被拖动行: " ,e['row']);
                console.log('原始下标:',e['sort']);
                console.log('移动到:',e['moveTo']);
                console.log('整根列表:',e['list']);
                console.log('=== confirm end ===');
            }
        }
    }
 </script>

 <style lang="scss">
    .row-content{
        flex-direction: row;
        align-items: center;
        padding-left: 10rpx;
        padding-right: 10rpx;

        .row-content-icon{
            width: 60rpx;
            height: 60rpx;
            border-radius: 6rpx;
        }
    }
    .row-drag{
        width: 44px;
        height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;

        .drag-icon{
            width: 60rpx;
            height: 60rpx;
        }
    }
 </style>

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问