Vue 中用原生 div 实现拖拽传值
前端
- # vue
- # drag-and-drop
- # html
在页面里做一个简单拖拽时,不一定一上来就需要引入拖拽库。原生的 div 就支持拖拽,只要给元素加上 draggable="true"。
<template>
<div draggable="true">
可拖拽元素
</div>
</template>
这样元素就可以被拖起来了。不过如果只是这样写,拖到另一个元素上松开时,浏览器默认行为可能不会按预期把它当成一个可放置区域。
让目标元素可以接收拖拽
目标元素需要处理 dragover 事件,并阻止默认行为。在 Vue 里可以直接写成:
<template>
<div @dragover.prevent>
拖到这里
</div>
</template>
这一步的作用是告诉浏览器:这个元素允许被拖拽内容放置。否则即使拖到了目标元素上,松开时也可能表现为不接收拖拽。
拖拽时传值
如果拖拽过程中需要把一些数据带到目标元素,可以在拖拽开始时通过 dataTransfer 写入数据。
<template>
<div
draggable="true"
@dragstart="handleDragStart"
>
可拖拽元素
</div>
</template>
const handleDragStart = (e: DragEvent) => {
e.dataTransfer?.setData('schema', JSON.stringify({ a: '123' }))
}
这里的 'schema' 是自定义的数据类型名称,后面接收时用同一个名称取出来即可。
在目标元素接收值
目标元素监听 drop 事件,在松开时读取前面写入的数据。
<template>
<div
@dragover.prevent
@drop="handleDrop"
>
拖到这里
</div>
</template>
const handleDrop = (e: DragEvent) => {
e.preventDefault()
const raw = e.dataTransfer?.getData('schema')
if (!raw) return
const data = JSON.parse(raw)
console.log(data)
}
完整的流程就是:
- 拖拽元素加上
draggable="true"。 - 在
dragstart里用dataTransfer.setData()写入数据。 - 目标元素使用
@dragover.prevent允许放置。 - 在
drop里用dataTransfer.getData()取回数据。
这样就可以用浏览器原生能力完成一个简单的拖拽传值。