懒加载介绍
由于在点击节点时才进行该层数据的获取,默认情况下 Tree 无法预知某个节点是否为叶子节点, 所以会为每个节点添加一个下拉按钮,如果节点没有下层数据,则点击后下拉按钮会消失。 同时,你也可以提前告知 Tree 某个节点是否为叶子节点,从而避免在叶子节点前渲染下拉按钮。
注:如果一棵树设置了懒加载,那么即使这棵树原先就有data,也需要每层每层的resolve数据
懒加载案例
<template>
<el-card>
<el-tree ref="treeRef" :props="props" :data="data" node-key="label" :load="loadNode" @check-change="handleCheck" lazy show-checkbox />
</el-card>
</template>
const treeRef = ref();
interface Tree {
label: string;
leaf?: boolean;
children?: Tree[];
}
const props = {
label: 'label',
children: 'zones',
isLeaf: 'leaf',
};
const data: Tree[] = ref([
{
label: 'Level one 1',
children: [
{
label: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
},
],
},
],
},
]);
const loadNode = async (node: Node, resolve: (data: Tree[]) => void) => {
console.log('node',node)
};
如上述所述,当给tree设置了懒加载,即使tree设置了:data="data" ,这棵树仍然是没有数据的,因为要在懒加载中把数据添加给每层节点
我们可以像下面这样来给懒加载添加数据
1)当level===0,也就是页面初始化时,把node.data给了页面,也就是节点0,此时页面会展示
2)虽然我们在level===0的时,把data给了页面,该data是有children数据的,但是这并不代表当你点开level one 1 会看到底下的数据,因为懒加载需要一层一层的给 因此我们可以采用该判断来继续给数据,即:当该node底下有children时,就把children直接resolve给页面即可
if (node.data.children && node.data.children.length > 0) { resolve(node.data.children); }
3)最后就是真正的懒加载,当node没有children时,我们就拿当前node的label或者value去获取接口,进而把得到的数据再给页面,这就是懒加载的流程
// 懒加载是一层一层实现的,必须给每一层都提供数据,即使最开始有data,也需要一层层继续给数据
if (node.level === 0) {
resolve(node.data as Tree[]);
} else if (node.data.children && node.data.children.length > 0) {
resolve(node.data.children);
} else {
const req = node.data.label;
console.log('req', req);
const { data } = await getLazyData(); //获取参数
console.log(data);
resolve(data);
}
};
/**
* 这是我mock的一份懒加载数据
*
*/
Mock.mock("/mock/getLazyData","get",{
message: "success",
data:[
{
label: 'leaf',
leaf: true,
},
{
label: 'zone',
children:[{
label:'zone-1',
leaf:true
}]
},
],
code: 200,
})
懒加载回显
我们常会思考,如果我需要回显的是一个懒加载中的数据,那么我在组件挂载的时候进行tree的setCheckedKeys,但是懒加载的数据必须得逐级点开才能得到,那么回显吗?答案是可以的。
onMounted(() => {
//给树设置回显,即使是懒加载的数据,当数据出来时,也是可以回显勾选的
treeRef.value.setCheckedKeys(['zone-1']);
});
check-change中如何获取懒加载的数据
如果此时有个需求是:后端需要的数据只是父级节点,所有子级节点都不要,举例:
其实这个很好理解,树形数据都是有层级的,当有了最大层级的数据,后端肯定不需要底下的数据了
那么我们可以怎么做呢?
我们借助check-change事件
我们可以定义一个空数组A,把每次选中的data放入数组中
我们再定一个需要废弃的空数组B,把每次选中data的children递归循环放入
最后把B从A中剔除,这样A里就只有父级节点了
但是我们发现一个问题如下:
const checkedData=[]//定义一个空数组
const uselessData=[]//定义一个废弃数组
const handleCheck = (d: any, checked: boolean, a: any) => {
console.log('选中的data', d); //只能拿到原始data中的数据,但是拿不到懒加载的数据
checkedData.push(d.label)//把选中的data放入数组中
const fn = (data) => {
data.forEach((item) => {
uselessData.push(item.label);
if (item.children && item.children.length) fn(item.children);
});
};
if (d.children && d.children.length) {
fn(d.children);
}
console.log(uselessData);
因此最后的结果是
解决办法:
通过getNode可以拿到当前选中的node,然后在通过递归把数据放入废弃的数组,但是觉得好麻烦啊~不知道有没有大神能支支招
const handleCheck = (d: any, checked: boolean, a: any) => {
console.log(treeRef.value.getNode(d)); //可以通过childNodes拿到所有节点,包括懒加载的
};