更新记录
1.0.0(2025-12-04)
1.0.0
平台兼容性
uni-app(3.6.16)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
easy-drag
uni-easy-drag,uni-app 一键拖拽组件,开箱即用,轻量级 & 最佳体验
特性
- ✅ 多平台支持:支持 H5、小程序、App 等多端
- ✅ 触摸 & 鼠标支持:同时支持触摸屏和鼠标操作
- ✅ 平滑动画:拖拽过程流畅,带有视觉反馈
- ✅ 自定义插槽:支持自定义拖拽项和占位符样式
- ✅ 轻量级:无额外依赖,开箱即用
安装
# 通过 HBuilderX 插件市场安装
# 或直接复制 uni_modules/easy-drag 到项目目录
快速开始
基础用法
强烈推荐使用作用域插槽来自定义拖拽项,这样可以根据拖拽过程中的状态(是否经过当前项)来添加不同的样式。
<template>
<view>
<easy-drag
:list="appList"
@onDrop="handleDrop"
>
<!-- 自定义拖拽项 -->
<template #box="{ boxItem }">
<view class="custom-item">
<image :src="boxItem.icon" class="icon" />
<text class="name">{{ boxItem.name }}</text>
</view>
</template>
</easy-drag>
</view>
</template>
<script setup>
import { ref } from 'vue'
const appList = ref([
{ id: 1, name: '应用1' },
{ id: 2, name: '应用2' },
{ id: 3, name: '应用3' },
])
const handleDrop = (event) => {
console.log('拖拽完成:', event)
// 重新排序列表
const { draggedIndex, dropIndex } = event
const [draggedItem] = appList.value.splice(draggedIndex, 1)
appList.value.splice(dropIndex, 0, draggedItem)
}
</script>
自定义样式
<template>
<view>
<easy-drag
:list="appList"
:wraperStyle="{ display: 'flex', flexWrap: 'wrap', gap: '10px' }"
@onDrop="handleDrop"
>
<!-- 自定义拖拽项 -->
<template #box="{ boxItem }">
<view class="custom-item">
<image :src="boxItem.icon" class="icon" />
<text class="name">{{ boxItem.name }}</text>
</view>
</template>
<!-- 自定义占位符 -->
<template #placeholder>
<view class="custom-placeholder">
<text>📥 放置到这里</text>
</view>
</template>
</easy-drag>
</view>
</template>
<style scoped>
.custom-item {
width: 80px;
height: 80px;
background: #f5f5f5;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
}
.custom-placeholder {
background: rgba(59, 130, 246, 0.1);
border: 2px dashed #3b82f6;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
}
</style>
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
list |
Array |
[] |
必需 - 用于渲染的列表数据,每个项必须包含 id 字段 |
wraperStyle |
Object |
{} |
容器样式,用于覆盖默认布局样式 |
showPlaceHolder |
Boolean |
true |
是否展示拖拽占位符 |
itemStyle |
Function |
(id, index) => ({}) |
排列的元素样式,入参是当前项的id和index,返回值是当前项对应的样式Object;慎用,尤其,关键的几个定位属性,除非你真的知道你在干什么 |
list 数据结构
const list = [
{ id: 1, name: '项目1', icon: '/static/icon1.png' },
{ id: 2, name: '项目2', icon: '/static/icon2.png' },
// ... 更多项目
]
事件
| 事件名 | 参数 | 说明 |
|---|---|---|
onDrop |
{ draggedIndex: number, dropIndex: number } |
拖拽完成时触发,返回拖拽项的原始索引和目标位置索引 |
onDrop 事件示例
const handleDrop = (event) => {
const { draggedIndex, dropIndex } = event
console.log(`从位置 ${draggedIndex} 拖拽到位置 ${dropIndex}`)
// 更新列表顺序
const [draggedItem] = appList.value.splice(draggedIndex, 1)
appList.value.splice(dropIndex, 0, draggedItem)
}
插槽 (Slots)
#box - 自定义拖拽项
作用域参数: boxItem - 当前列表项的数据,额外添加 isOver - 拖拽过程中是否经过当前项,可以做一些交互样式韩式
<template #box="{ boxItem, isOver }">
<view class="custom-box">
<image :src="boxItem.avatar" class="avatar" />
<text class="title">{{ boxItem.title }}</text>
</view>
</template>
#placeholder - 自定义占位符
拖拽过程中显示的放置指示器
<template #placeholder>
<view class="custom-placeholder">
<text>🎯 放置目标</text>
</view>
</template>
样式类名
组件内置了以下 CSS 类名,可用于自定义样式:
.container- 最外层容器.drag-box- 每个拖拽项容器.placeholder- 拖拽占位符.cursor-move- 拖拽时鼠标样式
注意事项
- 列表项必须包含 id 字段:用于 Vue 的 key 管理
- 样式覆盖:使用
wraperStyle,itemStyle或 CSS 类名覆盖默认样式 - 性能优化:对于大量数据,建议使用虚拟滚动
- 多端兼容:组件已处理各平台的差异,无需额外配置
示例代码
更新日志
查看 changelog.md 获取最新版本信息。
技术支持
可**联系我
如有问题请提交 Issue 或联系开发者。

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 3
赞赏 0
下载 11724778
赞赏 1818
赞赏
京公网安备:11010802035340号