问题一:实现el-tree 删除、添加、编辑后默认展开该节点
操作视频如下
el-tree节点操作后仍展开
节点代码
<template><el-treev-loading="loading"ref="tree"element-loading-text="加载中"highlight-current:data="treeData":props="defaultProps"node-key="id":default-expanded-keys="defaultKey"@node-click="handleNodeClick"/>
</template>
实现步骤:
- 通过el-tree的
node-click
事件获取点击节点的数据 - 通过递归获取点击节点的所有父级的id
- 通过
node-key
和default-expanded-keys
属性绑定获取的父级id和自身id
逻辑代码如下
data() {return {treeData:[], // el-tree数据defaultKey:[], // 默认展开的数据defaultProps: {children: 'child',label: 'name',},}},methods: {/*** @func 获取当前点击节点数据,根据当前数据查询该数据的所有父级id* @params {Object} data* @return void*/async handleNodeClick(data) {// 使用递归——编辑、删除、添加完成之后该节点仍是展开状态let dataArr = this.findParentIds(this.treeData, data.id);this.defaultKey = dataArr;},/*** 根据树子节点ID查找所有父节点ID* @param {array} dataSource 树形结构数据源* @param {number} nodeId 子节点ID* @returns {array} 包含所有父节点ID的数组,按照从根节点到直接父节点的顺序排序*/findParentIds(dataSource, nodeId) {const parentIds = []; // 用于存储所有父节点ID的数组// 定义一个递归函数,用于遍历整棵树并查找子节点的所有父节点function traverse(node, nodeId) {if (node.id === nodeId) {// 如果当前节点的ID等于子节点的ID,则表示已经找到了子节点,可以开始向上查找父节点return true; // 返回true表示已经找到了子节点}if (node.child) {// 如果当前节点有子节点,则继续遍历子节点for (const childNode of node.child) {if (traverse(childNode, nodeId)) {// 如果在子节点中找到了子节点的父节点,则将当前节点的ID添加到父节点ID数组中,并返回true表示已经找到了子节点parentIds.push(node.id);return true;}}}return false; // 如果当前节点不是子节点的父节点,则返回false}// 从根节点开始遍历整棵树,并调用递归函数查找子节点的所有父节点for (const node of dataSource) {if (traverse(node, nodeId)) {// 如果在当前节点的子树中找到了子节点的父节点,则直接退出循环break;}}return parentIds.length ? [...parentIds, nodeId] : [nodeId]; // 返回所有父节点ID和自身id},}
问题二:el-tree 同级节点拖拽并进行前后端排序+筛选
操作视频如下
el-tree 同级拖拽排序
节点代码
<template><el-treev-loading="loading"ref="tree"element-loading-text="加载中"highlight-current:data="treeData":props="defaultProps":draggable="true":allow-drop="allowDrop":filter-node-method="filterNode"@node-drop="handleDrop"/>
</template>
实现步骤:
- 通过el-tree的
draggable
属性开启可拖拽功能 - 通过el-tree的
allow-drop
属性写方法判断节点能否被拖拽 - 通过el-tree的
node-drop
属性获取拖拽成功节点的子级id - 将获取拖拽节点的子集id传给后端
- 外加筛选是用到了
filter-node-method
属性
逻辑代码如下
/*** @func 判断拖拽的数据是否是同一层级*/allowDrop(draggingNode, dropNode, type) {if (draggingNode.level === dropNode.level) {if (draggingNode.data.pid === dropNode.data.pid) {return type === 'prev' || type === 'next';}} else {return false;}},/*** @func 拖拽成功事件*/handleDrop(draggingNode, dropNode) {let list = [];// 获取子级idfor (let item of dropNode.parent.childNodes) {list.push(item.data.id);}// 将该节点排序后的子级id传给后端this.funGetDragSort(list);},/*** @func 调后端接口——子级id传给后端*/async funGetDragSort(val) {await datamanagement.updateCategorySort(val);},/*** @func 左侧el-tree控件搜索* @return void*/filterNode(value, data) {if (!value) return true;return data.name.indexOf(value) !== -1;},