更新记录

1.0.0(2025-03-24)

feat: 拖拽组件1.0


平台兼容性

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

wsd-draggable 可拖拽列表

Props

属性 描述 类型 是否必填 默认值
dataSource(v-model) 绑定数据集 DragItem[] true -
keyField 主键字段名 string - 'id'
labelField 显示标签字段名 string - 'label'
grid 网格数 number - 1
gap 间距 number - 0
dragClass 开启拖拽列表项样式类 string - 'is-drag'
moveClass 拖拽移动列表项样式类 string - 'is-move'
dropClass 拖拽放置列表项样式类 string - 'is-drop'
customClass 自定义列表样式类 string - -
customItemClass 自定义列表项样式类 string - -
longpress 是否长按开启拖拽 boolean - true
debounce 拖拽时延,s number - 25
viewport 边界 UniApp.NodeInfo - -
absolute 列表项完全在边界内 boolean - false
offset 列表项拖拽距离边界间距 number - 10
dragMode 显示标签字段名) "swap" | "move" - "move"
moveScale 长按列表项缩小比例 number - 0.9

Events

事件 描述 类型
on-drag 拖拽开始时触发 (source: DragItem, sourceIndex: number, touch: TouchEvent) => void
on-move 拖拽过程中触发 (touch: TouchEvent) => void
on-drag 拖拽结束时触发 (target: DragItem, source: DragItem, targetIndex: number, sourceIndex: number, touch: TouchEvent) => void
on-change 拖拽发生变化时触发 (target: DragItem, source: DragItem, targetIndex: number, sourceIndex: number, touch: TouchEvent) => void
update:dataSource 列表变化时触发 (dataSource: DragItem[]) => void

Slots

名称 描述 类型
default 默认作用域插槽,用于自定义列表元素 {item: DragItem, index: number}

Example

<template>
    <view class="wsd-demo-page">
        <scroll-view
            :scroll-y="!disableScroll"
            id="demo-scroll-view"
            class="wsd-demo-page__scroll"
        >
            <wsd-draggable
                :grid="3"
                :gap="10"
                :viewport="viewport"
                :longpress="false"
                v-model:dataSource="dataSource"
                customItemClass="demo-draggable-item"
                @onDrag="disableScroll = true"
                @onDrop="disableScroll = false"
            ></wsd-draggable>
        </scroll-view>
    </view>
</template>

<script setup>
import { getCurrentInstance, nextTick, onMounted, ref } from "vue";
import { getNodeRect } from "../utils";

const data = [];
for (let i = 0; i <= 42; i++) {
    data.push({
        id: i,
        label: `label-${i}`,
    });
}

const _instance = getCurrentInstance();
const dataSource = ref(data);
const viewport = ref(null);
const disableScroll = ref(false);

onMounted(() => {
    nextTick(async () => {
        viewport.value = await getNodeRect("#demo-scroll-view", _instance);
    });
});
</script>

<style lang="scss" scoped>
.wsd-demo-page {
    position: relative;
    box-sizing: border-box;
    padding: 15vh 20px 5vh;
    height: 100vh;
    width: 100vw;

    &__scroll {
        position: relative;
        height: 100%;
        width: 100%;
    }

    :deep(.demo-draggable-item) {
        border: 1px solid #d8d8d8;
        border-radius: 4px;
        height: 60px;
    }
}
</style>

Infos

使用作用域插槽进行渲染时,如果数据存在增加/删除这类操作,插槽内容会被复用渲染,可能存在渲染更新异常。建议直接拷贝组件,直接在拷贝的组件中实现列表项渲染以及数据更新

隐私、权限声明

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

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

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

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