项目需求:
1. 需要拖拽效果。
2. 把A菜单的子菜单拖动到B菜单
项目难点:
把A菜单下的子菜单拖动到B菜单,如何判断插入的节点!
问题解析:
1.拖动效果 : 在h5 中drag Api
要让一个元素有支持拖拽,需要在标签上做一个标识。
<div draggable="true"></div>
元素在拖放过程中触发的事件
1. dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发
2. darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发
3. dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
4. dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
5. dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
6. drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
7. dragend:事件主体是被拖放元素,在整个拖放操作结束时触发
我们需要用到146
1.在拖动得时候 我们要记录一下拖动得是那个元素 所以用到dragstart
2.拖到目标节点,我们要记录一下拖放到那个元素里 所以用dragover
3. 我们把元素拖进去之后,我们要插入,所以用drop
大白话的讲解
去书店买书,1先找到书 2.去找到收银员 3.确认付款
代码
<div id="index">
<div class="left">
<div class="Meum" v-for="item in list" :key="item.id">
<div class="Ameum" @click="show(item.id,1)">{{item.name}}</div>
<div class="Bmeum" v-show="item.isShow">
<div v-for="Z_Item in item.children" :key='Z_Item.id' :draggable="draggable" @dragstart="dragStart($event,Z_Item.id)"> {{ Z_Item.name }} </div>
</div>
</div>
</div>
<div class="right">
<div class="Meum" v-for="item in list1" :key="item.id">
<div class="Ameum" @click="show(item.id,2)" @dragover='dragover($event,item.id)' @drop="drop($event,item.id)">{{item.name}}</div>
<div class="Bmeum" v-show="item.isShow">
<div class="cccccc" v-for="Z_Item in item.children" :key='Z_Item.id' :draggable="draggable" >
<input type="checkbox" @change="onChange(Z_Item)">
<span>{{ Z_Item.name }}</span>
<span @click="detele(Z_Item.id)">删除</span>
</div>
</div>
</div>
</div>
</div>
<script>
export default {
name: 'Home',
data(){
return{
// isShow:true,
draggable:true,
list: [
{
name: '一级菜单A',
isShow:true,
id: 'a',
children: [
{name: '一级菜单A子菜单1-1', id: 'a1-1',state:false},
{name: '一级菜单A子菜单1-2', id: 'a1-2',state:false},
{name: '一级菜单A子菜单1-3', id: 'a1-3',state:false}
]
},
{
name: '一级菜单B',
isShow:true,
id: 'b',
children: [
{name: '一级菜单B子菜单2-1', id: 'b2-1',state:false},
{name: '一级菜单B子菜单2-2', id: 'b2-2',state:false},
{name: '一级菜单B子菜单3-3', id: 'c2-3',state:false}
]
},
{
name: '一级菜单C',
isShow:true,
id: 'c',
children: [
{name: '一级菜单C子菜单3-1', id: 'c3-1',state:false},
{name: '一级菜单C子菜单3-2', id: 'c3-2',state:false},
{name: '一级菜单C子菜单3-3', id: 'c3-3',state:false}
]
}
],
list1: [
{
name: '一级菜单A',
isShow:true,
id: 'ca',
children: [
{name: '一级菜单A子菜单1-1', id: 'a1-1',state:false},
{name: '一级菜单A子菜单1-2', id: 'a1-2',state:false},
{name: '一级菜单A子菜单1-3', id: 'a1-3',state:false}
]
},
{
name: '一级菜单B',
isShow:true,
id: 'bb',
children: []
},
],
}
},
mounted(){
},
methods:{
dragStart (ev,keyId) {
this.dom = ev.target
console.log(keyId)
//如果左侧没有数据,禁止拖动
if(this.list1.length<0){
this.draggable = false
}else{
this.draggable = true
}
},
dragover (event) {
console.log(`拖进来了`)
if(this.dom != event.target){
//默认浏览器不支持拖动,如果下面的方法支持拖动
event.preventDefault()
}
},
show(id,type){
if(type === 1){
for(let i=0;i<this.list.length; i++){
if(this.list[i].id === id){
this.list[i].isShow = !this.list[i].isShow
}
}
}else{
for(let i=0;i<this.list1.length; i++){
if(this.list1[i].id === id){
this.list1[i].isShow = !this.list1[i].isShow
}
}
}
},
drop(ev,keyId){
//插入节点,不懂的可以单独百度。。。。
ev.target.nextSibling.appendChild(this.dom)
},
onChange(item){
item.state = !item.state
console.log(item.state)
},
//删除
detele(id){
console.log(id)
}
}
}
</script>
<style scoped>
#index{
display: flex;
}
.left{
width: 400px;
height: 500px;
border: 1px solid #ccc;
}
.Ameum{
background: #ccc;
cursor: default;
text-align: start;
}
.Bmeum{
background: yellowgreen;
text-align: start;
margin-left: 5%;
cursor: default;
user-select:none;
}
.right{
width: 400px;
height: 500px;
border: 1px solid #ccc;
margin-left: 20px;
}
.cccccc{
display: flex;
justify-content: space-between;
}
</style>
遇到的坑
咱们现在的页面都是div套div。所以在插入节点的时候,会出现失传已久的事件冒泡。我们需要阻止事件冒泡
event.stopPropagation();
没有具体写代码,只是阐述了一个思路而已,不懂可以留言,小菜鸟,不喜欢勿喷
附上一片优秀的 h5 drag Api 详解https://www.cnblogs.com/wuya16/p/DragApi.html