1.通过在render中给每个树节点添加domProps属性,使节点支持拖拽效果,也可以选择在父组件传入draggable属性控制树是否可拖拽
domProps: {
draggable: this.draggable
},
2.dragstart方法获取到原节点和它的父节点,drop方法获取目标节点,将原节点从父节点删除并添加到目标节点children中
<template>
<div>
<Tree ref="tree" :data="data" :render="renderContent">
</Tree>
</div>
</template>
<script type="text/ecmascript-6">
export default {
name: 'dragTree',
props: {
data: {
type: Array,
default() {
return [];
}
},
draggable: {
type: Boolean,
default: true
},
showCheckbox: {
type: Boolean,
default: false
},
},
data() {
return {
currentNode: {},
parentNode: {},
dragNode: {},
dropNode: {},
isChild: false,
treeData: [],
filterTreeData: [{
title: '全选',
expand: true,
classCode: '',
children: []
}],
}
},
methods: {
renderContent(h, {root, node, data}) {
data.selected = data.title === this.currentNode.title;
return h('span', {
domProps: {
draggable: this.draggable
},
style: {
display: 'inline-block'
},
class: {'node-selected': data.selected},
on: {
click: () => {
this.handleSelect(root, node, data);
},
//拖拽开始,获取拖拽元素和拖拽元素的父节点
dragstart: (e) => {
e.stopPropagation();
this.currentNode = data;
this.dragNode = data;
this.parentNode = root[node.parent].node;
// this.parentNode = this.getParentNode(data.parentCode, this.data);
},
//把拖拽元素从父节点中删除
dragend: (e) => {
e.preventDefault();
},
//源对象在悬停在目标对象上时
//阻止默认行为,使得drop可以触发
dragover: (e) => {
e.preventDefault();
},
//把拖拽元素从原节点上删除,并添加到目标对象上
drop: (e) => {
e.preventDefault();
e.stopPropagation();
this.dropNode = data;
let isChild = this.isChildNode (this.dropNode, this.dragNode);
if (!isChild) {
let index = this.parentNode.children.indexOf(this.dragNode);
this.parentNode.children.splice(index, 1);
let children = this.dropNode.children || [];
children.push(this.dragNode);
}
}
}
}, [
h('span', [
h('Icon', {
props: {
type: data.expand ? 'mt-folder-open' : 'md-folder'
},
style: {
marginRight: '8px',
color: '#2d8cf0',
fontSize: '16px'
}
}),
h('span', data.title)
])
])
},
/**
* 判断目标节点是否是拖拽节点的子节点
* @param dropNode 目标节点
* @param dragNode 拖拽节点
*/
isChildNode (dropNode, dragNode) {
if (dragNode.children) {
dragNode = dragNode.children;
for(let i = 0; i < dragNode.length; i++) {
if (dragNode[i] === dropNode) {
return true;
} else {
return this.isChildNode(dropNode, dragNode[i]);
}
}
} else {
return false;
}
},
handleSelect (root, node, data) {
this.$set(data, 'selected', true);
this.currentNode = data;
this.$emit('on-select-change', data);
},
getParentNode(parentCode, data) {
for (let i = 0; i < data.length; i++) {
if (data[i].classCode === parentCode) {
return data[i];
} else if (data[i].children) {
return this.getParentNode(parentCode, data[i].children);
}
}
return false;
}
}
}
</script>
<style lang="less">
.node {
&-selected {
background-color: #d5e8fc;
}
}
</style>
本文介绍了一种在前端开发中实现可拖拽树形组件的方法,通过在树节点中添加draggable属性,使节点支持拖拽。并在拖拽过程中,通过dragstart和drop方法获取原节点和目标节点,实现节点的重新排序或移动。
3433

被折叠的 条评论
为什么被折叠?



