el-tree树形实现鼠标拖拽,以及通过点击上下移按钮实现tree节点上下移动

el-tree树形实现鼠标拖拽,以及通过点击上下移按钮实现tree节点上下移动

1.业务需求:
  • vue项目开发需求是:使用el-tree组件实现树形鼠标拖拽功能,并且在每一个树形节点的后面增加上移和下移的按钮,通过点击按钮实现节点上下移动。
2.解决方案:
  • el-tree组件使用HTML如下(我使用的这种是可以自定义树形节点内容的写法):

  • <el-tree
                        ref="menutree"
                        :data="treeData"
                        node-key="sysResourcesId"
                        :default-expand-all="false"
                        @node-drag-start="handleDragStart"
                        @node-drag-enter="handleDragEnter"
                        @node-drag-leave="handleDragLeave"
                        @node-drag-over="handleDragOver"
                        @node-drag-end="handleDragEnd"
                        @node-drop="handleDrop"
                        draggable
                        :expand-on-click-node="false"
                        v-loading="loading"
                        :props="defaultProps"
                        :allow-drop="allowDrop"
                        :allow-drag="allowDrag">
                        <template slot-scope="{ node, data}">
                          <div class="menuRowBox">
                            <div :id="data.sysResourcesId" style="font-size:15px;"
                                 @dblclick="workUpdate(node,data)">
                              <i style="padding-right: 3px" :class="'iconfont '+ data.icon"></i>
                              {{data.resourcesName}}
                            </div>
                            <div class="upBox">
                              <el-button size="mini" type="text" plain icon="el-icon-top" @click="menuMoveF(node,data,'up')">上移</el-button>
                              <el-button size="mini" type="text" plain icon="el-icon-bottom" @click="menuMoveF(node,data,'down')">下移</el-button>
                            </div>
                          </div>
                        </template>
                      </el-tree>
    
  • 第一步,el-tree组件实现树形鼠标拖拽的功能其实是比较好实现的,el-tree组件自带有相关的方法与属性,调用即可实现,js 相关函数如下(到这里已经可以实现鼠标拖拽的功能了):

  • // 节点开始拖拽时触发的事件
          handleDragStart(node, ev) {
            console.log('drag start', node,ev)
            this.rightPush = true
            this.leftPush = false
            ev.dataTransfer.setData("item", JSON.stringify(node.data));
          },
          // 拖拽进入其他节点时触发的事件
          handleDragEnter(draggingNode, dropNode, ev) {
            console.log('tree drag enter: ', dropNode.label)
          },
          // 拖拽离开某个节点时触发的事件
          handleDragLeave(draggingNode, dropNode, ev) {
            console.log('tree drag leave: ', dropNode.label)
          },
          // 在拖拽节点时触发的事件(类似浏览器的 mouseover 事件)
          handleDragOver(draggingNode, dropNode, ev) {
            console.log('tree drag over: ', dropNode.label)
          },
          // 拖拽结束时(可能未成功)触发的事件
          handleDragEnd(draggingNode, dropNode, dropType, ev) {
            console.log('tree drag end: ', dropNode && dropNode.label, dropType)
          },
          // 拖拽成功完成时触发的事件
          handleDrop(draggingNode, dropNode, dropType, ev) {
            console.log('tree drop: ',draggingNode, dropNode, dropType)
          },
          // 拖拽时判定目标节点能否被放置。type 参数有三种情况:'prev'、'inner' 和 'next'
          allowDrop(draggingNode, dropNode, type) {
            console.log(416,draggingNode,dropNode,type)
            return true
          },
          // 判断节点能否被拖拽
          allowDrag(draggingNode) {
            return true
          },
    
  • 第二步,通过点击上下移按钮实现tree节点上下移动的功能就需要自己写方法了,这里我结合了el-tree组件里面的 insertBefore方法( 为 Tree 的一个节点的前面增加一个节点 )、insertAfter方法( 为 Tree 的一个节点的后面增加一个节点 )、remove方法( 删除 Tree 中的一个节点 ),insertBefore方法与insertAfter方法只能实现新增的功能,并不能改变原来的节点,所以需要结合删除去实现移动功能。

  • 	// 移动点击函数(node:当前节点,data:当前节点的data,type:区分上下移动)
          menuMoveF(node,data,type) {
            // 将变动之前的node备份
            let copyNode = {...node}
            copyNode.previousSibling = {...node.previousSibling}
            copyNode.nextSibling = {...node.nextSibling}
            window.sessionStorage.setItem('menuNode',CircularJSON.stringify(copyNode))
            let nodeData = {}
            if (type==='up') {
               // 上移
              if (node.previousSibling) {
                // 删除原先的node
                this.$refs.menutree.remove(node.data)
                // 拿到copy的node
                nodeData = CircularJSON.parse(window.sessionStorage.getItem('menuNode'))
                // 复制该node到指定位置(参数:1. 要增加的节点的 data 2. 要增加的节点的后一个节点的 data、key 或者 node)
                this.$refs.menutree.insertBefore(nodeData.data,nodeData.previousSibling.data)
                window.sessionStorage.removeItem('menuNode')
              } else {
                this.$message.warning('该菜单已经是当前层最上级')
              }
            } else {
              // 下移
              if (node.nextSibling) {
                this.$refs.menutree.remove(node.data)
                nodeData = CircularJSON.parse(window.sessionStorage.getItem('menuNode'))
                // 参数:1. 要增加的节点的 data 2. 要增加的节点的前一个节点的 data、key 或者 node
                this.$refs.menutree.insertAfter(nodeData.data,nodeData.nextSibling.data)
                window.sessionStorage.removeItem('menuNode')
              } else {
                this.$message.warning('该菜单已经是当前层最下级')
              }
            }
          },
    
  • 最终效果如下(这里是上移,下移同理):
    在这里插入图片描述
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_34917408/article/details/107407272