Skip to content

LimeDnd 拖拽排序组件

一个功能强大的拖拽排序组件,支持单列和多列布局,可用于列表重排序、宫格排序等场景。组件提供了丰富的自定义选项,包括禁用特定项、使用拖拽手柄等功能,可满足各种复杂的交互需求。

文档链接

📚 组件详细文档请访问以下站点:

安装方法

  1. 在uni-app插件市场入口 中搜索并导入lime-dnd
  2. 导入后可能需要重新编译项目
  3. 在页面中使用l-dndl-dnd-iteml-dnd-handle组件
  4. 需要源码才能运行,不支持试用。请谨慎购买。

代码演示

基础用法

最简单的拖拽排序组件用法,创建一个可拖拽的列表。

html
<l-dnd v-model:list="basicList" @change="onBasicChange">
  <l-dnd-item v-for="(item, index) in basicList" :key="item['id']" :index="index">
    <view class="item">
      <text class="text">{{ item['text'] }}</text>
    </view>
  </l-dnd-item>
</l-dnd>
js
// 基础列表数据
const basicList = ref([
  { id: 1, text: '项目 1' },
  { id: 2, text: '项目 2' },
  { id: 3, text: '项目 3' },
  { id: 4, text: '项目 4' },
  { id: 5, text: '项目 5' },
]);

// 事件处理函数
const onBasicChange = (newList: UTSJSONObject[]) => {
  console.log('列表更新:', newList);
};

多列布局

创建一个多列的网格布局,适用于宫格排序场景。

html
<l-dnd v-model:list="gridList" :itemHeight="120" :column="3" :gap="5">
  <l-dnd-item v-for="(item, index) in gridList" :key="item['id']" :index="index">
    <view class="grid-item">
      <image class="grid-item__image" :src="item['image']"></image>
      <text class="grid-item__text">{{ item['text'] }}</text>
    </view>
  </l-dnd-item>
</l-dnd>
js


// 网格列表数据
const gridList = ref([
  { id: 1, text: '图片 1', image: 'https://example.com/image1.jpg' },
  { id: 2, text: '图片 2', image: 'https://example.com/image2.jpg' },
  { id: 3, text: '图片 3', image: 'https://example.com/image3.jpg' },
  { id: 4, text: '图片 4', image: 'https://example.com/image4.jpg' },
  { id: 5, text: '图片 5', image: 'https://example.com/image5.jpg' },
  { id: 6, text: '图片 6', image: 'https://example.com/image6.jpg' },
]);

// 事件处理函数
const onGridChange = (newList: UTSJSONObject[]) => {
  console.log('网格列表更新:', newList);
};

禁用特定项

可以设置某些项不可拖拽,适用于需要固定位置的元素。

html
<l-dnd v-model:list="disabledList" :itemHeight="50" :column="3">
  <l-dnd-item v-for="(item, index) in disabledList" :key="item['id']" :index="index"
    :disabled="item['disabled']">
    <view class="item" :class="{ 'item--disabled': item['disabled'] == true }">
      <text class="text">{{ item['text'] }}</text>
    </view>
  </l-dnd-item>
</l-dnd>
js
// 包含禁用项的列表数据
const disabledList = ref([
  { id: 1, text: '禁用项 1', disabled: true },
  { id: 2, text: '禁用项 2', disabled: true },
  { id: 3, text: '可拖拽项 1', disabled: false },
  { id: 4, text: '可拖拽项 2', disabled: false },
  { id: 5, text: '可拖拽项 3', disabled: false },
  { id: 6, text: '禁用项 3', disabled: true },
]);

// 事件处理函数
const onDisabledChange = (newList: UTSJSONObject[]) => {
  console.log('禁用列表更新:', newList);
};

使用拖拽手柄

通过拖拽手柄控制拖拽行为,提供更精确的操作体验。

html
<l-dnd v-model:list="basicList" @change="onBasicChange" useHandle>
  <l-dnd-item v-for="(item, index) in basicList" :key="item.id" :index="index">
    <view class="item">
      <text class="text">{{ item['text'] }}</text>
      <l-dnd-handle>
        <l-icon name="view-list"></l-icon>
      </l-dnd-handle>
    </view>
  </l-dnd-item>
</l-dnd>

边缘滚动(试验)

当用户拖拽项目到容器边缘时,会自动触发页面滚动,使得长列表的拖拽排序更加流畅

html
<l-dnd v-model:list="scrollList" 
	longpress 
	auto-scroll
	@drag-move="onMove" 
	@drop="onDrop"
	@edge-scroll="onPageEdgeScroll">
	<l-dnd-item v-for="(item, index) in scrollList" :key="item['id']" :index="index">
		<view class="item">
			<text class="text">{{ item['text'] }}</text>
			<l-dnd-handle>
				<l-icon style="color: var(--doc-title-color, #000000E6);" class="text" name="view-list"></l-icon>
			</l-dnd-handle>
		</view>
	</l-dnd-item>
</l-dnd>
js
const scrollList = ref([
	{ id: 1, text: '可拖拽项 1' },
	{ id: 2, text: '可拖拽项 2' },
	{ id: 3, text: '可拖拽项 3' },
	{ id: 4, text: '可拖拽项 4' },
	{ id: 5, text: '可拖拽项 5' },
	{ id: 6, text: '可拖拽项 6' },
	{ id: 7, text: '可拖拽项 7' },
	{ id: 8, text: '可拖拽项 8' },
	{ id: 9, text: '可拖拽项 9' },
	{ id: 10, text: '可拖拽项 10' },
	{ id: 11, text: '可拖拽项 11' },
	{ id: 12, text: '可拖拽项 12' },
	{ id: 13, text: '可拖拽项 13' },
	{ id: 14, text: '可拖拽项 14' },
	{ id: 15, text: '可拖拽项 15' },
	{ id: 16, text: '可拖拽项 16' },
	{ id: 17, text: '可拖拽项 17' },
	{ id: 18, text: '可拖拽项 18' },
	{ id: 19, text: '可拖拽项 19' },
	{ id: 20, text: '可拖拽项 20' },
	{ id: 21, text: '可拖拽项 21' },
	{ id: 22, text: '可拖拽项 22' },
	{ id: 23, text: '可拖拽项 23' },
	{ id: 24, text: '可拖拽项 24' },
	{ id: 25, text: '可拖拽项 25' },
	{ id: 26, text: '可拖拽项 26' },
	{ id: 27, text: '可拖拽项 27' },
	{ id: 28, text: '可拖拽项 28' },
])

let isScrolling = false; // 是否正在滚动
let nowPageScrollY = 0;  // 当前页面滚动位置
let scrollTimer: number | null = null; // 滚动定时器


onPageScroll((opts) => {
	if (isScrolling) return;
	nowPageScrollY = opts.scrollTop;
})

function onMove(e : UTSJSONObject) {
	isScrolling = true
}

function onPageEdgeScroll(e : UTSJSONObject) {
	isScrolling = true;
	// 计算目标滚动位置(减小滚动幅度,避免抖动)
	nowPageScrollY += (e.deltaY as number);
	uni.pageScrollTo({
		scrollTop: nowPageScrollY,
		duration: 0,
		success: () => {
			isScrolling = false;
		}
	});
}

function onDrop(e : UTSJSONObject) {
	isScrolling = false;
}

Vue2使用说明

本插件使用了composition-api,请按照官方教程配置。

关键配置代码(在main.js中添加):

js
// main.js
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)

快速预览

导入插件后,可以直接使用以下标签查看演示效果:

html
<!-- 代码位于 uni_modules/lime-dnd/components/lime-dnd -->
<lime-dnd />

插件标签说明

标签名说明
l-dnd拖拽容器组件
l-dnd-item拖拽项组件
l-dnd-handle拖拽手柄组件
lime-dnd演示标签

API文档

Dnd Props 属性说明

属性名说明类型默认值
list拖拽项列表数据object[][]
itemHeight每个拖拽项的高度Number50
column列数,用于多列布局Number1
gap项目之间的间隔Number0
scrollDiff滚动差值Number1
useHandle是否只能通过拖动手柄组件来触发拖拽Booleanfalse
longpress是否只能通过拖动 长按来触发拖拽Booleanfalse
autoScroll是否到达边缘自动滚动Booleanfalse
container获取指定组件容器的DOM矩形函数() => Promise<DOMRect>-
lClass自定义类名String-
lStyle自定义样式String | Object-

Dnd Events 事件

事件名说明回调参数
update:list列表数据更新时触发list: Array
drag-start开始拖拽时触发{ itemIndex: Number }
drag-move拖拽移动时触发{ itemIndex: Number, insertIndex: Number, deltaX: Number, deltaY: Number }
edge-scroll边缘滚动时触发{ deltaY: Number }
drop拖拽结束时触发{ itemIndex: Number, insertIndex: Number }

DndItem Props 属性说明

属性名说明类型默认值
index项目在列表中的索引,必填Number-
disabled是否禁用拖拽Booleanfalse
lClass自定义类名String-
lStyle自定义样式String | Object-

DndItem Slots 插槽

名称说明插槽参数
default拖拽项内容{ active: Boolean, passive: Boolean }

DndHandle Props 属性说明

属性名说明类型默认值
lClass自定义类名String-
lStyle自定义样式String | Object-

DndHandle Slots 插槽

名称说明
default拖拽手柄内容

主题定制

组件提供了以下CSS变量,可用于自定义样式:

变量名称默认值描述
--l-dnd-duration300ms拖拽动画过渡时长(uniappx app暂时无效)
--l-dnd-dragging-shadow$shadow-3拖拽时的阴影效果(uniappx app暂时无效)

支持与赞赏

如果你觉得本插件解决了你的问题,可以考虑支持作者:

支付宝赞助微信赞助

源代码

组件源码