vue与H5结合使用,实现菜单的拖拽效果
业务需求,将菜单一下面的子菜单,使用拖拽添加到菜单二的子菜单中
点击一级菜单,显示对应一级菜单下的子菜单,拖拽子菜单到其他任意一级菜单下
HTML
<div id="dragBox">
<div class="targetBox">
<div>目标盒子 一级菜单</div>
<p :id="item.id" class="blue"
v-for="item in list"
@drop="dropTarget($event, item.id)"
@dragover.prevent="dragover($event)"
@click="childrenlist = item.children;deleteFirstId = item.id"
:key="item.id">{{item.name}} </p>
</div>
<div class="dragBox">
<div>拖拽的盒子 二级菜单</div>
<p :id="item.id" class="red"
draggable="true"
@dragstart="dragStart($event)"
v-for="(item, index) in childrenlist"
:key="index">{{item.name}} </p>
</div>
</div>
数据
childrenlist: [],
list: [
{
name: '一级菜单A',
id: 'a',
children: [
{name: '一级菜单A子菜单1-1', id: 'a1-1'},
{name: '一级菜单A子菜单1-2', id: 'a1-2'},
{name: '一级菜单A子菜单1-3', id: 'a1-3'}
]
},
{
name: '一级菜单B',
id: 'b',
children: [
{name: '一级菜单B子菜单2-1', id: 'b2-1'},
{name: '一级菜单B子菜单2-2', id: 'b2-2'},
{name: '一级菜单B子菜单3-3', id: 'c2-3'}
]
},
{
name: '一级菜单C',
id: 'c',
children: [
{name: '一级菜单C子菜单3-1', id: 'c3-1'},
{name: '一级菜单C子菜单3-2', id: 'c3-2'},
{name: '一级菜单C子菜单3-3', id: 'c3-3'}
]
}
],
deleteFirstId: ''
JS实现
dragStart (ev) {
ev.dataTransfer.setData('text', ev.target.id)
},
dragover (ev) {
// console.log(ev)
// ev.preventDefalut()
},
dropTarget (ev, targetId) {
// 防止火狐浏览器打开页面
ev.preventDefault()
ev.stopPropagation()
// 获取拖拽的子菜单ID
let id = ev.dataTransfer.getData('text')
// 获取目标一级菜单ID
let target = targetId
/*
1. 删除拖拽的一级菜单中的子菜单
2. 添加到目标一级菜单中
*/
// 删除项
let templist = []
for (let i in this.list) {
if (this.list[i].id === this.deleteFirstId) {
// 获取删除的子菜单索引
let index = this.childrenlist.findIndex(item => item.id === id)
templist = this.childrenlist.splice(index, 1)
this.$set(this.list, i, Object.assign(this.list[i], {children: this.childrenlist}))
}
}
for (let j in this.list) {
if (this.list[j].id === target) {
this.$set(this.list, j, Object.assign(this.list[j], {children: [...templist, ...this.list[j].children]}))
}
}
console.log(id)
console.log(ev.target.id)
},
拖拽到一级菜单B中
特别注意两点
1. dragover必须加prevent
2. 为了解决火狐浏览器拖拽后打开新页面的问题,drop方法必须加上下面两行代码
ev.preventDefault()
ev.stopPropagation()