更新记录
1.0.3(2025-10-15) 下载此版本
修复微信小程序不可用
1.0.2(2025-10-13) 下载此版本
添加拖拽结束处理标志和添加模式状态
1.0.1(2025-09-26) 下载此版本
- 添加拖拽开始事件拦截功能
- 添加item-click事件处理
- 为默认网格项添加删除按钮样式配置
平台兼容性
uni-app(4.66)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | - | √ | √ | √ | - | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
liaction-grid-drag
基于Vue 3的可拖拽网格组件,提供灵活的拖拽排序、项目管理功能,适用于UniApp项目。
特性
- 可自定义网格布局(列数、间距、内边距等)
- 支持固定项目(不可拖拽)
- 内置删除功能,支持确认对话框
- 支持添加项目功能
- 丰富的样式自定义选项
- 响应式设计,自适应窗口大小
- 提供完整的事件回调机制
- 支持项目级别的样式覆盖
基本用法
<template>
<view class="container">
<liaction-grid-drag
:items="gridItems"
:columns="3"
:draggable="true"
:show-delete-button="true"
:show-add-slot="true"
:useCustomDeleteModal="useCustomDeleteModal"
@sortEnd="onSortEnd"
@add-item="onAddItem"
@delete-item="onDeleteItem"
@item-click="onItemClick"
@show-delete-modal="onShowDeleteModal"
>
<template #item="{ item, index }">
<view style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;">
<image :src="item.icon" mode="aspectFit" style="width: 50%; height: 50%;" />
<text>{{ item.name }}</text>
</view>
</template>
</liaction-grid-drag>
</view>
</template>
<script>
export default {
data() {
return {
gridItems: [
{ id: '1', name: '项目1', icon: '/static/icons/1.png' },
{ id: '2', name: '项目2', icon: '/static/icons/2.png' },
{ id: '3', name: '项目3', icon: '/static/icons/3.png' },
{ id: '4', name: '项目4', icon: '/static/icons/4.png' },
{ id: '5', name: '项目5', icon: '/static/icons/5.png' }
],
useCustomDeleteModal: false
}
},
methods: {
onSortEnd(items) {
this.gridItems = items;
console.log('排序结果:', items);
},
onAddItem() {
const newItem = {
id: Date.now().toString(),
name: `新项目${this.gridItems.length + 1}`,
icon: `/static/icons/${Math.floor(Math.random() * 9) + 1}.png`
};
this.gridItems.push(newItem);
},
onDeleteItem({ item, index }) {
this.gridItems.splice(index, 1);
},
onItemClick({ item, index }) {
console.log('点击了项目:', item, '索引:', index);
},
onShowDeleteModal({ item, index, confirm, cancel }) {
// 显示自定义删除确认弹窗
// 用户确认后调用 confirm()
// 用户取消后调用 cancel()
}
}
}
</script>
<style>
.container {
padding: 20px;
}
</style>
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| columns | Number | 3 | 网格列数,必须为正整数 |
| items | Array | [] | 网格项目数据数组 |
| gap | Number | 10 | 项目间距(像素),必须为非负数 |
| padding | Number | 10 | 容器内边距(像素),必须为非负数 |
| draggable | Boolean | false | 是否允许拖拽 |
| aspectRatio | Number | 1 | 项目宽高比,必须大于0 |
| showDeleteButton | Boolean | false | 是否显示删除按钮 |
| showAddSlot | Boolean | false | 是否显示添加按钮 |
| maxItemCount | Number | Infinity | 最大项目数量限制 |
| maxHeight | Number | Infinity | 容器最大高度(像素) |
| minHeight | Number | 100 | 容器最小高度(像素) |
| useDefaultItems | Boolean | false | 是否使用默认项目数据 |
| defaultItemCount | Number | 9 | 默认项目数量 |
| defaultItemsDraggable | Boolean | true | 默认项目是否可拖拽 |
| defaultItemsDeletable | Boolean | true | 默认项目是否可删除 |
| useCustomDeleteModal | Boolean | false | 是否使用自定义删除弹窗 |
样式相关属性
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| itemBgColor | String | '#409eff' | 项目背景色 |
| fixedItemBgColor | String | '#909399' | 固定项目背景色 |
| addSlotBgColor | String | '#f0f2f5' | 添加按钮背景色 |
| itemTextColor | String | 'white' | 项目文本颜色 |
| addSlotTextColor | String | '#606266' | 添加按钮文本颜色 |
| itemBorderRadius | Number | 8 | 项目圆角(像素) |
| itemTextSize | Number | 14 | 项目文本大小(像素) |
| itemTextWeight | String/Number | 'normal' | 项目文本粗细 |
| itemTextFontFamily | String | 'sans-serif' | 项目文本字体 |
| itemTextStyle | Object | {} | 项目文本额外样式 |
删除按钮相关属性
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| deleteBtnSize | Number | 24 | 删除按钮大小(像素) |
| deleteBtnBgColor | String | '#ff0000' | 删除按钮背景色 |
| deleteBtnTextColor | String | '#fff' | 删除按钮文本颜色 |
| deleteBtnFontSize | Number | 12 | 删除按钮字体大小 |
| deleteBtnText | String | '×' | 删除按钮文本 |
| deleteBtnMaxDigitsLength | Number | 2 | 数字类型删除按钮文本最大长度 |
| deleteBtnMaxLength | Number | 1 | 非数字类型删除按钮文本最大长度 |
删除确认对话框属性
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| deleteConfirmTitle | String | '提示' | 确认对话框标题 |
| deleteConfirmMessage | String | '确定要删除这个项目吗?' | 确认对话框消息 |
| deleteConfirmConfirmText | String | '确定' | 确认按钮文本 |
| deleteConfirmCancelText | String | '取消' | 取消按钮文本 |
滚动条相关属性
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| scrollbarWidth | Number | 6 | 滚动条宽度(像素),必须大于等于2 |
| scrollbarTrackColor | String | '#f5f5f5' | 滚动条轨道颜色 |
| scrollbarThumbColor | String | '#ccc' | 滚动条滑块颜色 |
| scrollbarThumbHoverColor | String | '#aaa' | 滚动条滑块悬停颜色 |
| scrollbarRadius | Number | 3 | 滚动条圆角(像素) |
Item 数据结构
每个网格项目可以包含以下属性:
| 属性名 | 类型 | 说明 |
|---|---|---|
| id | String/Number | 项目唯一标识 |
| name | String | 项目名称(默认显示文本) |
| draggable | Boolean | 该项是否可拖拽(覆盖全局设置) |
| deletable | Boolean | 该项是否可删除 |
| fixed | Boolean | 该项是否固定(固定项不可拖拽) |
| deleteBtnSize | Number | 该项删除按钮大小(覆盖全局设置) |
| deleteBtnBgColor | String | 该项删除按钮背景色(覆盖全局设置) |
| deleteBtnTextColor | String | 该项删除按钮文本颜色(覆盖全局设置) |
| deleteBtnFontSize | Number | 该项删除按钮字体大小(覆盖全局设置) |
| deleteBtnText | String | 该项删除按钮文本(覆盖全局设置) |
| deleteBtnMaxDigitsLength | Number | 该项数字类型删除按钮文本最大长度(覆盖全局设置) |
| deleteBtnMaxLength | Number | 该项非数字类型删除按钮文本最大长度(覆盖全局设置) |
| 其他自定义属性 | 任意 | 自定义数据,可在插槽中使用 |
事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| sortEnd | 排序完成时触发 | items: 排序后的项目数组 |
| sort-complete | 排序完成时触发(与sortEnd相同,兼容性别名) | items: 排序后的项目数组 |
| update:items | 项目数组更新时触发 | items: 更新后的项目数组 |
| add-item | 点击添加按钮时触发 | 无 |
| delete-item | 确认删除项目时触发 | { item: 删除的项目, index: 删除的索引 } |
| delete-confirmed | 确认删除项目时触发(与delete-item相同,用于明确区分确认状态) | { item: 删除的项目, index: 删除的索引 } |
| delete-canceled | 取消删除项目时触发 | { item: 取消删除的项目, index: 项目索引 } |
| drag-start | 开始拖拽时触发 | { item: 拖拽的项目, index: 项目索引 } |
| drag-end | 结束拖拽时触发 | { item: 拖拽的项目, index: 项目索引 } |
| item-click | 点击项目时触发 | { item: 点击的项目, index: 项目索引 } |
| show-delete-modal | 使用自定义删除弹窗时触发(需要设置useCustomDeleteModal为true) | { item: 要删除的项目, index: 项目索引, confirm: 确认回调, cancel: 取消回调 } |
插槽
| 插槽名 | 说明 | 插槽参数 |
|---|---|---|
| item | 自定义项目内容 | { item: 项目数据, index: 项目索引, isDragging: 是否正在拖拽, isDraggable: 是否可拖拽 } |
| delete-button | 自定义删除按钮 | { item: 项目数据, index: 项目索引 } |
| addSlot | 自定义添加按钮 | 无 |
部分示例
基本用法
<liaction-grid-drag
:useDefaultItems="true"
/>

固定项目示例
<template>
<liaction-grid-drag
:items="gridItems"
:columns="4"
:draggable="true"
:show-delete-button="true"
/>
</template>
<script>
export default {
data() {
return {
gridItems: [
{ id: '1', name: '可拖拽项目', draggable: true },
{ id: '2', name: '固定项目', fixed: true }, // 通过fixed属性固定项目
{ id: '3', name: '可拖拽项目2', draggable: true },
{ id: '4', name: '不可删除', deletable: false }
]
}
}
}
</script>

自定义项目样式
<template>
<liaction-grid-drag :items="gridItems" :columns="3" :gap="15" itemBgColor="#67c23a" itemTextColor="#fff"
itemBorderRadius="12">
<template #item="{ item, isDragging }">
<view class="custom-item" :class="{ 'dragging': isDragging }">
<image :src="item.image" mode="aspectFit" class="item-image" />
<text class="item-title">{{ item.title }}</text>
<text class="item-desc">{{ item.description }}</text>
</view>
</template>
</liaction-grid-drag>
</template>
<script>
export default {
data() {
return {
gridItems: [
{
image: '/static/icons/1.png',
title: 'Item 1',
description: 'Description 1'
},
{
image: '/static/icons/2.png',
title: 'Item 2',
description: 'Description 2'
},
{
image: '/static/icons/3.png',
title: 'Item 3',
description: 'Description 3'
},
{
image: '/static/icons/4.png',
title: 'Item 4',
description: 'Description 4'
},
{
image: '/static/icons/5.png',
title: 'Item 5',
description: 'Description 5'
}
],
}
}
}
</script>
<style scoped>
.custom-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px;
box-sizing: border-box;
}
.item-image {
width: 60px;
height: 60px;
margin-bottom: 8px;
}
.item-title {
font-weight: bold;
margin-bottom: 4px;
}
.item-desc {
font-size: 12px;
text-align: center;
}
.dragging {
opacity: 0.8;
}
</style>

常见问题与解决方案
问题:拖拽时项目位置不正确
解决方法:确保没有在样式中覆盖组件内部的定位样式,特别是movable-view元素的定位属性。
问题:固定项目被意外移动
解决方法:检查项目数据中fixed属性是否正确设置,确保固定项目的draggable属性为false。
问题:滚动条样式不符合预期
解决方法:通过自定义滚动条相关props来调整样式,或者在全局样式中定义相应的滚动条样式覆盖。
问题:在小屏幕设备上拖拽不流畅
解决方法:可以适当增加DRAG_THRESHOLD值来减少计算频率,或者减少同时显示的项目数量。
注意事项
- 组件使用了Vue 3的Composition API,确保您的项目支持Vue 3
- 组件依赖UniApp的movable-area和movable-view组件,确保在非UniApp环境中适当适配
- 对于大量数据(如超过50项),可能需要优化性能或考虑虚拟列表
- 拖拽操作可能在某些低性能设备上有延迟,建议根据实际场景调整参数
- 在自定义样式时,避免直接修改组件内部的类名样式,建议使用插槽和自定义类
- 当设置
fixed: true属性时,组件会自动将该项的draggable属性设置为false - 自定义删除弹窗功能需要同时设置
useCustomDeleteModal: true并监听show-delete-modal事件

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 36
赞赏 0
下载 10868264
赞赏 1799
赞赏
京公网安备:11010802035340号