代码样例
<el-tree
class="tree-border"
:data="ecpmenuOptions"
show-checkbox
node-key="menuItemId"
ref="ecpmenu"
empty-text="加载中,请稍候"
:props="defaultProps1"
></el-tree>
data 就是树形结构的数据
show-checkbox 默认展示选择框
node-key 就是每一个树杈的id值
empty-text 是数组为空时候显示的内容
prop:就是每一个数组展示的内容,孩子展示对应的字段
在使用树形接口的时候我们会发现获取用户已经选择的内容有两种方式
this.$refs.ecpmenu.getCheckedNodes() 返回的是对应node树
this.$refs.ecpmenu.getCheckedKeys(); 返回的是menuItemId数组
我们还有半选择的情况
getHalfCheckedNodes()
getCheckedKeys()
在这里强调一下,如果我们的menuItemId的值是Number类型,那么我们用起来getCheckedKeys()会很方便,但是也不排除有字符串类型,字符串类型我们使用getCheckedNodes()情况就可以了。
修改时候反显用户的选择情况 如果id值是字符串,反选我们用节点
注意:这种情况需要把半选的父级去掉就可以了
this.$refs.ecpmenu.setCheckedNodes([{menuItemId:"MU580201",menuName: "办事项"}])
如果是数字类型,直接拿到相应key数组就可以了
this.$refs.ecpmenu.setChecked(v, true ,false);
在这里引申一下,我们再使用node的时候后台一般会渲染相应的菜单树带半选的父级菜单,而我们只需要已选的子级菜单就可以,所以需要把多维数组转为一纬数组
convertToSimpleArray(arr){
const result = [];
const flatten = (node) => {
result.push(node);
if (node.childrenMenus) {
for (const child of node.childrenMenus) {
flatten(child);
}
}
}
for (const node of arr) {
flatten(node);
}
return result
},
延申一下,我们在渲染全量菜单树的时候,data数据后端并没有处理过,需要我们把一维转为多维,我们怎么办呢?
function arrayToTree(array) {
const map = {};
const result = [];
// 构建一个映射,以便快速查找每个节点
array.forEach(item => {
map[item.id] = { ...item, children: [] };
});
// 将节点添加到树结构中
array.forEach(item => {
if (item.parentId) {
// 如果有 parentId,则将当前节点添加到父节点的 children 数组中
if (map[item.parentId]) {
map[item.parentId].children.push(map[item.id]);
}
} else {
// 没有 parentId 的节点将被视为根节点
result.push(map[item.id]);
}
});
return result;
}
// 示例数据
const flatArray = [
{ id: 1, name: 'Node 1', parentId: null },
{ id: 2, name: 'Node 2', parentId: null },
{ id: 3, name: 'Node 3', parentId: null},
{ id: 6, name: 'Node 1.1.1', parentId: 1 },
{ id: 7, name: 'Node 1.1.2', parentId: 1 },
{ id: 4, name: 'Node 2.1.1', parentId: 2 },
{ id: 5, name: 'Node 2.1.2', parentId: 2 },
];
const treeData = arrayToTree(flatArray);
console.log('一维数组转成树形数据-----------',treeData)
设置全选状态
<el-checkbox v-model="ecpmenuNodeAll" @change="handleCheckedTreeNodeAll($event, 'ecpmenu')">全选/全不选</el-checkbox>
// 树权限(全选/全不选)
handleCheckedTreeNodeAll(value, type) {
if (type == 'menu') {
this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
} else if (type == 'dept') {
this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
}
if(type == 'ecpmenu') {
this.$refs.ecpmenu.setCheckedNodes(value ? this.ecpmenuOptions: []);
}
},
设置展开状态
<el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
let treeList = this.ecpmenuOptions;
for (let i = 0; i < treeList.length; i++) {
this.$refs.ecpmenu.store.nodesMap[treeList[i].menuItemId].expanded = value;
}
设置父子联动
<el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
// 树权限(父子联动)
handleCheckedTreeConnect(value, type) {
if(type == 'ecpmenu'){
this.ecpform.menuCheckStrictly = value ? true: false;
}
if (type == 'menu') {
this.form.menuCheckStrictly = value ? true: false;
} else if (type == 'dept') {
this.form.deptCheckStrictly = value ? true: false;
}
},