3
树结构在项目中其实还是比较常见的,本篇文章以饿了么UI中的el-tree组件为例,讲述一下树组件的懒加载的实现步骤。当然,顺带吐槽一下官方文档的案例写的不太接地气

问题描述

树组件如果数据比较多的话,一次性把整棵树的数据都请求到,略有耗时。所以为了优化性能,我们就要实现树组件懒加载的效果,也就是当我们点击树节点的时候,再去向后端发请求,获取对应点击的树节点下的数据。这样的话,点击哪里,加载哪里,性能会提高不少。

效果图

我们先看一下最终的成品效果图

懒加载前端代码

html部分

<template>
  <div class="box">
    <div class="leftBox">
      <el-tree lazy :load="loadNode" :props="props" node-key="id">
      </el-tree>
    </div>
  </div>
</template>

js部分

<script>
export default {
  data() {
    return {
      props: {
        label: "name",
        isLeaf: "isLeaf",
      },
    };
  },
  methods: {
    loadNode(node, resolve) {
      //如果展开第一级节点,从后台加载一级节点列表
      if (node.level == 0) {
        this.loadfirstnode(resolve);
      }
      //如果展开其他级节点,动态从后台加载下一级节点列表
      if (node.level >= 1) {
        this.loadchildnode(node, resolve);
      }
    },
    //加载第一级节点
    async loadfirstnode(resolve) {
      let params = {
        level: 0,
      };
      const res = await this.$api.getTreeData(params);
      return resolve(res.data);
    },
    //加载节点的子节点集合
    async loadchildnode(node, resolve) {
      // console.log("超过二级的", node, node.level);
      let params = {
        id: node.key,
      };
      const res = await this.$api.getTreeChildData(params);
      return resolve(res.data);
    },
  },
};
</script>

思路分析

首先,使用el-tree树组件必须指定lazy和load属性

  • lazy告知树组件开启懒加载模式,加上即可
  • load绑定的是一个函数,这个函数主要是用来在页面初始化加载的时候,用于向后端发请求获取el-tree的树结构的数据的。页面初始化加载,load绑定的函数会自动执行
注意,如果树组件开启了懒加载模式,就不用在el-tree组件标签中写:data="data属性了,因为load绑定的函数,有两个参数,node和resolve,node是树节点,而resolve又是一个函数,相当于高阶函数(函数柯里化)了,我们只需要把后端返回的数据(单层数组结构),放在这个函数里面,这个函数会自动把数据传递到树组件里面去,同时渲染视图

然后,我们需要和后端约定好传递的数据结构,即props中的配置

本例中是一个便于理解的简单el-tree的demo,所以就按照最简单的配置书写

  • data中的props中的label属性,就是平常指定的节点的名字,这个不赘述
  • data中的props中的isLeaf属性,指定的则是:是否是树组件中的叶子节点。什么是叶子节点?我们知道一棵树有很多分支(树枝),而树枝的末梢则是叶子,所以叶子节点就是树节点的最内层,最里层。所以,我们需要和后端沟通,让后端返回的树结构数据中,最内层数据加上isLeaf属性布尔值,为true就代表是最内层,为false,或者不加这个属性,就代表不是最内层。对应树组件的页面效果就是:为true的树组件,最内层不会有三角箭头。即到底了,没懒加载了
注意,因为树组件的懒加载是,点击树组件节点,加载下一层的数据,所以要和后端同事沟通,让后端接口数据不要一次性的返回整个树结构的数据,而是分层返回,点击那个树节点,树节点数据中会有id的,根据id发请求到后端,后端再把对应数据返回给前端,是数组结构的数据

接下来说说发请求这一块

因为树组件的load属性绑定的函数,初始化就会加载发请求,又因为树组件可以分为最外层和非最外层,所以在load绑定的函数中,本例是loadNode函数里面发请求,可以分两类:最外层和非最外层。(最外层level为0,非最外层levle大于0)所以就会有如下代码:

loadNode(node, resolve) {
  console.log('node节点数据记录了很多信息',node);
  console.log('resolve高阶函数给树组件赋值',node);
  //如果展开第一级节点,从后台加载一级节点列表(固定的)
  if (node.level == 0) {
    this.loadfirstnode(resolve);
  }
  //如果展开其他级节点,动态从后台加载下一级节点列表(可变的)
  if (node.level >= 1) {
    this.loadchildnode(node, resolve);
  }
},

我们打印node参数和resolve参数,发现分别是树节点和一个函数,树节点记录了很多信息,其中就有树的层级

node参数打印效果图

resolve参数打印效果图

最后注意后端返回的数据结构

初始化加载最外层西游记和三国演义节点

点击西游记加载孙悟空、猪八戒、沙和尚节点

完整代码地址

附上Gitee完整代码,方便大家理解,里面分为简化版的el-tree和优化版的el-tree

https://gitee.com/ah-shuai/de...


水冗水孚
1.1k 声望585 粉丝

每一个不曾起舞的日子,都是对生命的辜负