vue 实现可拖曳的树状结构图

最近用vue做了一个小项目--可拖曳的树状布局图。

Vue递归组件

布局通过Vue的递归组件实现

vue 实现可拖曳的树状布局图

机关利用flex,布局线由CSS伪类实现

需要留意的是居中机关,当X轴元素过多导致子元素宽度超出视图,元素居中后固然有转动条,但只能达到右边的内容,左边的内容会无法会见,可以把父元素配置为inline-flex,宽度配置为auto。虽然,假如是上述的布局则不会有这个问题,但碰着大数据渲染,照旧困扰我了一下午。

drag事件

首先在需要在拖动的元素上绑定draggable属性,除了<a>和<img>标签设默认为true,其他元素都需要配置下

然后是三个事件dragend、dragover、drop(用Vue写的,就不在事件前加on了)

留意dragover需要去除默认行为,在事件中给上$event.preventDefault(),不然拖曳时鼠标会有🚫符号,使拖动无效。

drag的元素把值传到drop的位置,需要利用$event.dataTransfer.setData("node", transNodeData)

"node"是相当于通报数据的变量名,需要先JSON.stringify()

methods:{ dragstart(e,nodeObj){ console.log('🐉drag移动的点位',nodeObj.name,); let transData=JSON.stringify(nodeObj)//拖曳通报已往的数据先转为JSON名目 e.dataTransfer.setData("node",transData) }, dragover(e){ e.preventDefault() }, drop(e,nodeObj){ console.log('🐉drop到的点位',nodeObj.name); let getData=JSON.parse( e.dataTransfer.getData("node")) console.log('获取了数据',getData); } }

vue 实现可拖曳的树状布局图

相识了这一点,接下来要做的就是把获取的拖曳点位数据放到安排点位的children数组中,并在dragend事件中把拖曳点位在父节点children数组中删除,节点的索引在dragstart事件触发时就获取,并通过eventBus这一组件通信方法通报给dragend(也可以利用Vuex)。

建设bus文件夹,新建index.js文件

import Vue from "vue" const busEvent= new Vue({ data(){ return{ dragNodeIndex:-1,//拖曳节点在父节点children数组中的index } }, created(){ this.$on("transDragNodeIndex", res=>{//通过$on来监听$emit,需要确保自界说事件在触发前被监听,也就是订阅先于宣布,不然无法监听到数据,我eventBus没怎么用过,这算是个坑 this.dragNodeIndex=res }) } }) export default busEvent

在组件中引入eventBus,此时在dragstart中通过$emit触发自界说事件后,$on就可以吸收到这个数据,在dragend中,可以通过eventBus获取这一索引,然后在数组中删除

vue 实现可拖曳的树状布局图

接下来就是做一些逻辑判定,譬喻父节点不能拖曳到子节点,先通过递归方法把父节点上所有子节点的name遍历进一个数组,假如drop位置的name在数组中就表白父到子了,配置状态为true,

ifFatherDragToSon(dragObj,dropObj){//判定是否父节点移动到了子节点 if (dragObj.children.length === 0) return false; let newArr = []; function getAllName(dragObj) { newArr.push(...dragObj.children); if (dragObj.children.length === 0) { return; } else { for (let i = 0; i < dragObj.children.length; i++) { getAllName(dragObj.children[i]); } } } getAllName(dragObj); if (newArr.includes(dropObj)) { return true; } return false; }

通过eventBus让dragend事件获取状态,为true直接return

拖曳到自身也不可,直接return。特意在拎壶冲点位下加了个子节点,主要就是为了验证通过节点在栈中的地点来判定,而不是依据name属性

vue 实现可拖曳的树状布局图

再一个就是提一下drag事件中的$event.dataTransfer.dropEffect,可以获取的值为move、copy、none、link,下图中当dropEffect为🚫时拖曳点位消失了,其实就是执行了dragend事件中的代码,而drop事件中的代码未执行,所以这一步需要先做流程节制。别的说明,差异欣赏器的默认dropEffect也是差异的,好比360欣赏器。

vue 实现可拖曳的树状布局图

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfysx.html