需求:
需要给用户分配菜单权限,源菜单是扁平化数组,需要将数组转化为树形结构,选中节点复选框,获取该节点的id及半选中的id
首先,封装树形结构方法
我们可以在utils中新建一个tree.js的文件,在该文件中封装一个构造树形结构的方法
例如:
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
*/
export function handleTree(data, id, parentId, children) {
let config = {
id: id || 'id',
parentId: parentId || 'parentId',
childrenList: children || 'children'
};
var childrenListMap = {};
var nodeIds = {};
var tree = [];
for (let d of data) {
let parentId = d[config.parentId];
if (childrenListMap[parentId] == null) {
childrenListMap[parentId] = [];
}
nodeIds[d[config.id]] = d;
childrenListMap[parentId].push(d);
}
for (let d of data) {
let parentId = d[config.parentId];
if (nodeIds[parentId] == null) {
tree.push(d);
}
}
for (let t of tree) {
adaptToChildrenList(t);
}
function adaptToChildrenList(o) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]];
}
if (o[config.childrenList]) {
for (let c of o[config.childrenList]) {
adaptToChildrenList(c);
}
}
}
return tree;
}
使用方法:可以将此方法全局挂载
import { handleTree } from "@/utils/tree";
//全局方法挂载
Vue.prototype.handleTree = handleTree
//此时我们就可以通过this.handleTree的方法将扁平化数组构造成二维数组了
//假设menuList是从后端获取到的扁平化数组
this.menuList = JSON.parse(
JSON.stringify(res.data.menus).replace(/menuName/g, "label")
);//此方法是为了将menuName通过正则的方式,改变属性名为label,这样是为了转为树形结构的时候,节点展示的内容为menuName
this.menuList = this.handleTree(this.menuList, "menuId");//将menuList造成树形结构数据
此时打印menuList就是转换为树形结构数据了
然后通过el-tree组件实现页面UI效果
<el-tree
:data="menuList"
show-checkbox
node-key="menuId"
:props="defaultProps"
:default-expand-all="false"
ref="dept"
class="tree-border"
accordion
>
//参数说明如下图
defaultProps: {
children: "children",
label: "label",
},
当我们勾选源菜单的内容时,页面都会有添加到目标菜单按钮,此时这个按钮需要触发一个事件
// 所有部门节点数据
getDeptAllCheckedKeys() {
// 目前被选中的部门节点
let checkedKeys = this.$refs.dept.getCheckedKeys();
// 半选中的菜单节点
let halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys();
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
console.log("checkedKeys", checkedKeys);
return checkedKeys;
},
//源表格添加到右侧表格
pushRight() {
this.$confirm("是否给该用户配置勾选的菜单?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
//勾选中及半选中的所有菜单节点的id数组,此时就可以把这个传给后端了
this.form.menuIds = this.getDeptAllCheckedKeys();
addTenantMenu({
menuIds: this.form.menuIds,
}).then(() => {
this.$message({
showClose: true,
message: "恭喜您,配置菜单成功!",
type: "success",
});
this.chooseChange(this.platformId);//重新发起get请求,获取改动后的内容
});
})
.catch(() => {
this.$message({
type: "info",
message: "配置取消!",
});
});
},
到这里,我们就完成了将后端返回的扁平化数组转化为树形结构,并且通过el-tree组件来实现页面的UI树形效果,并且节点带有复选框,勾选复选框时获取勾选中及半选中的所有id