知识点:
draggable:允许元素进行拖拽
@drop:当元素放下到drop元素触发
@dragstart:开始拖元素触发
prevent:拦截默认事件
dataTransfer:
dataTransfer 对象允许我们在开始拖动元素时设置数据,并在将元素放在拖放区中时访问相同的数据。
我们应该知道一些关于 dataTransfer 的属性和方法(如果要了解更多,请查看dataTransfer API 文档)。
dropEffect:当前的拖放操作(例如,移动,复制)
effectAllowed:指定拖放操作
setData(name,val):允许我们向dataTransfer对象添加值
getData(name):检索存储的值
具体效果
实现过程
创建一个 item 对象数组,对象的属性有:
- id:唯一的 ID,以便我们可以查找对象
- title:要显示文字
- list:它所属的列表。
data () {
return {
items: [
{
id: 0,
title: 'Item A',
list: 1
},
{
id: 1,
title: 'Item B',
list: 1
},
{
id: 2,
title: 'Item C',
list: 2
}]
}
}
创建两个计算属性用来把项目列表过滤为列表1中的项目和列表2中的项目。
computed: {
listOne () {
return this.items.filter(item => item.list === 1)
},
listTwo () {
return this.items.filter(item => item.list === 2)
}
}
然后把两个列表渲染出来
<template>
<div>
<div class='drop-zone'>
<div v-for='item in listOne' :key='item.title' class='drag-el'>
{{ item.title }}
</div>
</div>
<div class='drop-zone'>
<div v-for='item in listTwo' :key='item.title' class='drag-el'>
{{ item.title }}
</div>
</div>
</div>
</template>
渲染效果如下
这个时候我们渲染出来的元素是不能拖动的,我们需要给他们添加上draggable属性,这样就我们就可以拖动元素了
<div
class='drag-el'
v-for='item in listTwo'
:key='item.title'
draggable
>
{{ item.title }}
</div>
添加上draggable属性以后,我们就可以拖动元素了,不过还是无法它拖动到其他的地方
然后我们给它们的子元素添加一个@dragstart
的监听事件
<div
class='drag-el'
v-for='item in listTwo'
:key='item.title'
draggable
@dragstart='startDrag($event, item)'
>
{{ item.title }}
</div>
@dragstart
绑定的startDrag
事件是用于在拖动的时候给dataTransfer对象添加一个属性,把当前拖拽中的子容器ID给储存起来
startDrag: (evt, item) => {
evt.dataTransfer.dropEffect = 'move'
evt.dataTransfer.effectAllowed = 'move'
evt.dataTransfer.setData('itemID', item.id)
}
然后我们给它们各自的父元素一个接受可拖动元素的放置区域。
先添加调用 onDrop
方法的 drop
事件侦听器。
<div class='drop-zone' @drop='onDrop($event, 1)'>
<div v-for='item in listOne' :key='item.title' class='drag-el'>
{{ item.title }}
</div>
</div>
onDrop
方法内容如下,在当触发时再onDrop
中检索dataTransfer
储存的子容器的ID,然后把子容器置换到当前放下的父容器
onDrop (evt, listID) {
const itemID = evt.dataTransfer.getData('itemID')
const item = this.items.find(item => item.id == itemID)
item.list = listID
}
然后,我们来看一下实现的效果