树结构在项目中其实还是比较常见的,本篇文章以饿了么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/demo-of-el-tree