【el-tree】树形结构拖拽,拖动修改分组

简介: 【el-tree】树形结构拖拽,拖动修改分组

背景:


项目中有个左侧菜单,并且各级菜单中的元素是可以拖拽到别的菜单中去,也就是树形结构拖拽修改分组,下面我介绍我项目中使用el-tree进行拖拽分组的方式.


效果:

拖拽到某个节点的前后

首先我们使用的是饿了么组件中的[el-tree]组件,他本身是自带拖拽功能的,只需要加上一个属性:

draggable//是否开启拖拽节点功能,默认为false


去掉部分无关代码后的组件:

  <el-tree :data="groupList"
      node-key="id"
     :default-expanded-keys='defaultexpande' //默认展开所有节点 
     :props="defaultProps" @node-drop="handleDrop"
     draggable                         //开启可拖拽属性
     @node-drop="handleDrop"      //拖拽完成时触发的事件
     ref='tree'>
   </el-tree>


其中我的业务处理会放在@node-drop="handleDrop" ,拖拽结束事件中:

拖拽完成时触发的事件 参数依次为:被拖拽节点、结束拖拽时最后进入的节点、被拖拽节点的放置位置(before、after、inner)、event :


我的业务处理逻辑是:


因为节点被拖动后触发的事件能够告诉我们:


  1. 被拖拽节点的信息                      draggingNode
  2. 被拖拽节点进入的节点信息        dropNode
  3. 被拖拽节点的放置类型:               dropType
  4. 表示拖拽事件对象,包含了拖拽操作的相关信息,如拖拽起始位置、拖拽结束位置等。event    


两种情况


一种是拖拽到某个节点的内部:


拖拽到分组内部


另外一种情况是拖拽到某个节点的前后


拖拽到某个节点的前后


可能你会觉得这不也是拖拽到分组1的内部吗 ? 其实也没错,但是这种情况el-tree组件的拖拽事件识别的逻辑就是拖拽到了某个节点的前后,然后事件返回的参数会告诉你具体被拖拽到了哪个节点的前后.


注意:拖拽到节点内部的判定必须是直接将被拖拽节点拖拽到分组的上方 !如果是拖拽到某个分组中的某个位置的话,这种就属于被拖拽到了某个节点的前后了。


业务部分:


我的项目中,树形结构的分层是通过parentid的.而分组内部的顺序是通过每一项的sortCode来决定的. 而el-tree在拖拽完成后,el-tree所绑定的数组会自动的和视图同步,我们可以省去了操作这个数据移动的步骤,我们需要关心的就是拖拽后,如果节点的层级改变了,那么需要将被拖拽节点的pid修改成改变后的父节点的id,以及更新进入的那个分组的里面所有元素的Sortcode.


拖拽到某个节点的内部的情况:


6a8655acf32b49b3bde48b52defdaa14.png

下面进入代码:

 handleDrop(draggingNode, dropNode, dropType, ev) {
 if (dropType == 'inner') {
  //如果是进入了某个分组的内部
 draggingNode.data.parentId = dropNode.data.id //修改被拖拽节点的pid
//遍历修改SortCode
for (let i = 0; i < dropNode.children.length; i++) {
          const element = dropNode.children[i];
          element.sortCode = i
          this.ModifyMenu(element)  //发请求保存修改sortCode后的分组
        }
}
}


解析:


在拖拽后我们可以通过dropType知道这个被拖拽的节点是被拖到了draggingNode的前后还是某个节点的里面,所以如果dropType ==‘inner’说明被拖拽节点是被拖拽到了目标节点的内部,那么,我们需要将被拖拽节点的pid设置成目标节点的id: 然后修改进入的那个分组里面的所有子元素的SortCode. 然后发请求保存修改pid和SortCode后的节点. 这里根据后端接口设计不同会有不同 !


拖拽节点到某个分组前后的情况:  56cd0b5daf2286cd144486b6a021a008_90ac8cc22eef4e288a513d4f13961313.png

下面进入代码:

 handleDrop(draggingNode, dropNode, dropType, ev) {
 ........
      else {
        // 放到了某个节点的前后,那么pid也相同
        draggingNode.data.parentId = dropNode.data.parentId
        // 如果是放到了某个节点的前后,判断其有没有父节点
        if (dropNode.data.parentId && dropNode.data.parentId !== '-1') {
         //有父节点,说明是放到了某个分组中的某个节点的前后
          //修改整个分组的sortCode
          const activeiTemParent = this.findItemById(this.groupList, draggingNode.data.parentId)  //这里手写了一个通过id找数据的方法,通过被移动节点的pid可以找到它的父元素,于是遍历它的父元素,修改所有它父元素的子节点的SortCode
          for (let i = 0; i < activeiTemParent.children.length; i++) {
            const element = activeiTemParent.children[i];
            element.sortCode = i
            this.ModifyMenu(element)  //发请求保存修改后的数据
          }
        } else {
          // 没有父节点,说明是第一层分组  直接遍历整个数组修改第一层数据的SortCode即可
          for (let i = 0; i < this.groupList.length; i++) {
            const element = this.groupList[i];
            element.sortCode = i
            this.ModifyMenu(element)  //发请求保存修改后的数据
          }
        }
      }
    },
 // 找出Id对应的项
    findItemById(arr, id) {
      for (let i = 0; i < arr.length; i++) {
        const item = arr[i];
        if (item.id === id) {
          return item;
        } else if (item.children) {
          const result = this.findItemById(item.children, id);
          if (result) {
            return result;
          }
        }
      }
      return null;
    },


解析:


在拖拽后,进入我们的代码中的else说明节点是被拖拽到了某个节点的前后,说明被拖拽节点(draggingNode)与目标节点(dropNode)是同级的,也就是pid相同,那么,我们需要将被拖拽节点的pid设置成目标节点的pid , 然后这里我手写了一个通过id找元素的方法,因为我们有了被拖拽节点的pid,我们需要找到这个pid对应的数据,然后遍历它修改里面所有子元素的SortCode值. 然后发请求保存修改pid和SortCode后的节点. 这里根据后端接口设计不同会有不同 !


以上就是我实现使用el-tree完成拖拽修改分组的整个过程啦 ! 对你有用的话可以点个赞支持下哦 !


el-tree组件图标的自定义

https://blog.csdn.net/weixin_64530670/article/details/132418884


相关文章
|
JavaScript
Vue使用Element的表格Table显示树形数据,多选框全选无法选中全部节点
Vue使用Element的表格Table显示树形数据,多选框全选无法选中全部节点
381 0
|
JavaScript 前端开发 Java
ztree实现左边动态生成树,右边为具体信息功能
ztree实现左边动态生成树,右边为具体信息功能
62 0
|
2月前
|
前端开发 JavaScript 开发者
利用 el-select 和 el-tree 实现树形结构多选框联动功能
本文详细介绍了如何使用ElementUI中的el-select下拉选择器和el-tree树形控件来实现多功能联动选择器,包括多选、删除、搜索、清空选项等功能。通过树形控件展示复杂的层级结构,用户可以通过下拉选择树形节点,实时搜索节点,且支持批量选择和删除功能。文中提供了完整的HTML、JavaScript和CSS代码实现,帮助开发者快速集成此功能。
846 0
利用 el-select 和 el-tree 实现树形结构多选框联动功能
|
3月前
element中tree组件的选中获取和返显
本文介绍了如何在Element UI的tree组件中获取选中的节点值以及如何进行节点的默认选中(返显)。主要通过使用`getCheckedKeys()`和`getHalfCheckedKeys()`方法来获取完全和半选中的节点,然后使用`setCheckedKeys()`方法来设置默认选中的节点。
244 2
element中tree组件的选中获取和返显
|
5月前
|
JavaScript
【UI】 elementUI的select-tree组合下拉框,选择后下拉框不收起
【UI】 elementUI的select-tree组合下拉框,选择后下拉框不收起
291 1
|
5月前
|
前端开发 JavaScript
【定制需求】el-tree 树形控件实现:每级可单独选择,选择父级不选中子集,子集全部选中不自动选中父级,手写按钮可支持子集全选,以及取消子集全选,el-tree 树形控件取消父子级联动选择
【定制需求】el-tree 树形控件实现:每级可单独选择,选择父级不选中子集,子集全部选中不自动选中父级,手写按钮可支持子集全选,以及取消子集全选,el-tree 树形控件取消父子级联动选择
339 0
|
5月前
Element UI 树形控件Tree 【详解】el-tree 展开指定节点,判断是否存在指定节点
Element UI 树形控件Tree 【详解】el-tree 展开指定节点,判断是否存在指定节点
925 0
|
5月前
|
定位技术 API 数据格式
Element UI【详解】el-cascader 级联选择器 - 行政区划选择(可以选择任意一级),限定选择范围,获取并解析选中的节点
Element UI【详解】el-cascader 级联选择器 - 行政区划选择(可以选择任意一级),限定选择范围,获取并解析选中的节点
652 0
|
7月前
|
JavaScript
解决Vue 3 + Element Plus树形表格全选多选以及子节点勾选的问题
解决Vue 3 + Element Plus树形表格全选多选以及子节点勾选的问题