在vue项目中进行拖拽增加节点
- 因为项目需要写一个小demo,但是在网上没有找到很合适的,所以就自己用原生拖拽搞了一个,依旧不是很完善,但是还能用,后期可能会用antV的G6来替代,看缘分更新
- 废话不多说,还是上代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拖拽demo</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
<div id="div1" class="jiedian" @drop='drop($event)' @dragover="draglev">
<div>
<ul class="jdlc" v-for="(item,index) in tempList" :key="index" @dragover='allowDrop($event)' >
<li style="position: relative;">
<span class="tzbtn">{{item.title}}</span>
<i class="el-icon-error" @click="closeFn(index)"></i>
<div class="dropBox">
<div @drop="dragent($event,index,1)"></div>
<div @drop="dragent($event,index,2)"></div>
</div>
<ul v-for="(item,index) in item.children" :key="index">
<li>
<span>{{item.title}}</span>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="tree">
<ul v-for="(item,index) in data" :key="index" :draggable="true" @dragstart='drag($event)'>
<li>
<span>{{item.title}}</span>
<ul v-for="(item,index) in item.children" :key="index">
<li>
<span>{{item.title}}</span>
</li>
</ul>
</li>
</ul>
</div>
</div>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://unpkg.com/@better-scroll/core@latest/dist/core.js"></script>
<script src="https://unpkg.com/@better-scroll/core@latest/dist/core.min.js"></script>
<script>
new Vue({
el: '#app',
data: function () {
return {
tempList: [
{
id: '1',
title: "节点一",
status: true,
children: [
{
id: '1-1',
title: "节点1-1",
status: true,
},
{
id: '1-2',
title: "节点1-2",
status: true,
}
]
},
{
id: '2',
title: "节点二",
status: true,
children: [
{
id: '2-1',
title: "节点2-1",
status: true,
},
{
id: '2-2',
title: "节点2-2",
status: true,
}
]
},
],
data: [{
id: '3',
title: '一级 1',
status: true,
children: [{
id: '3-1',
title: '二级1',
status: true,
}
]
}, {
id: '4',
title: '一级 2',
status: true,
children: [{
id: '4-1',
title: '二级1',
status: true,
}, {
id: '4-2',
title: '二级2',
status: true,
}]
}],
defaultProps: {
children: 'children',
label: 'title'
}
}
},
methods: {
drag: function (e) { //start
let target=e.target;
let nodeList=e.target.parentNode.children;
this.targetIndex=this.tabIndex(target,nodeList);
},
drop: function (e) { //end
e.preventDefault();
},
allowDrop: function (e) { //moving
e.preventDefault();
e.stopPropagation()
console.log(222)
},
tabIndex(target,nodeList){
for(let i=0;i<nodeList.length;i++){
if(target===nodeList[i]){
return i;
}
}
},
dragent(e,index,flag){
var arr = this.data
if(flag === 1){
this.tempList.splice(index,-1,arr[this.targetIndex]);
}else if (flag === 2){
this.tempList.splice(index+1,0,arr[this.targetIndex]);
}
},
draglev(){
console.log(111)
},
closeFn(index){
this.tempList.splice(index,1);
console.log('del')
}
}
})
</script>
</body>
<style>
ul li {
list-style: none;
}
width: 800px;
height: 400px;
display: flex;
margin: 0 auto;
}
.jiedian {
width: 700px;
background:
padding: 40px;
overflow: auto;
}
.jiedian div{
height: 320px;
overflow: auto;
display: flex;
}
.jiedian .tzbtn {
width: 140px;
height: 20px;
display: inline-block;
border: 1px solid
background:
border-radius: 20px;
padding: 10px 0;
text-align: center;
}
.jiedian .jdlc {
position: relative;
display: inline-block;
}
.jiedian .jdlc li ul {
position: relative;
}
.jiedian .jdlc li ul li {
height: 32px;
}
.jiedian .jdlc li ul li span {
line-height: 62px;
}
.jiedian .jdlc:not(:last-child)::after {
content: ' ';
position: absolute;
left: 182px;
top: 20px;
width: 47px;
border: none;
border-top: 2px solid
}
.jiedian .jdlc li ul::before {
content: ' ';
position: absolute;
left: 18px;
height: 100%;
border: none;
border-left: 2px solid
}
.jiedian .jdlc li ul li:after {
content: ' ';
position: absolute;
top: 30px;
left: 20px;
width: 20px;
border: none;
border-top: 2px solid
}
.tree{
width: 100px;
background:
padding-top: 20px;
}
.tree ul{
width: 100px;
padding: 0;
margin-top: 0;
}
.tree ul li{
margin-left: 20px;
position: relative;
}
.tree ul li ul li{
height: 22px;
}
.tree ul li ul li span{
line-height: 38px;
}
.tree ul li ul li::after {
content: ' ';
position: absolute;
left: -10px;
top: 0px;
height: 21px;
border: none;
border-left: 2px solid
}
.tree ul li ul li::before {
content: ' ';
position: absolute;
left: -12px;
top: 16px;
height: 6px;
width: 6px;
border: none;
border-radius: 3px;
background:
}
.dropBox{
position: absolute;
left: 0;
top: 0;
display: flex;
height: 42px !important;
width: 100%;
}
.dropBox>div{
flex: 1;
height: 100%;
}
.el-icon-error {
display: inherit;
}
.el-icon-error:before {
content: "\e79d";
position: absolute;
top: -5px;
right: 5px;
}
</style>
</html>