elementUI中el-tree的懒加载

1,022 阅读3分钟

懒加载介绍

由于在点击节点时才进行该层数据的获取,默认情况下 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)
};

image.png 如上述所述,当给tree设置了懒加载,即使tree设置了:data="data" ,这棵树仍然是没有数据的,因为要在懒加载中把数据添加给每层节点 我们可以像下面这样来给懒加载添加数据

1)当level===0,也就是页面初始化时,把node.data给了页面,也就是节点0,此时页面会展示

image.png

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']);
});

image.png

image.png

image.png

image.png

image.png

check-change中如何获取懒加载的数据

如果此时有个需求是:后端需要的数据只是父级节点,所有子级节点都不要,举例:

image.png

image.png 其实这个很好理解,树形数据都是有层级的,当有了最大层级的数据,后端肯定不需要底下的数据了 那么我们可以怎么做呢? 我们借助check-change事件 我们可以定义一个空数组A,把每次选中的data放入数组中 我们再定一个需要废弃的空数组B,把每次选中data的children递归循环放入 最后把B从A中剔除,这样A里就只有父级节点了 但是我们发现一个问题如下:

image.png

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);

因此最后的结果是

image.png

解决办法:

通过getNode可以拿到当前选中的node,然后在通过递归把数据放入废弃的数组,但是觉得好麻烦啊~不知道有没有大神能支支招

const handleCheck = (d: any, checked: boolean, a: any) => {
  console.log(treeRef.value.getNode(d)); //可以通过childNodes拿到所有节点,包括懒加载的
};

image.png