在开发中经常会用到树形结构,数据是后端返回的,其余的操作都在前端完成,在此记录一些操作
最基础的用法,官方案例

<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>

<script>
  export default {
    data() {
      return {
        data: [{
          label: '一级 1',
          children: [{
            label: '二级 1-1',
            children: [{
              label: '三级 1-1-1'
            }]
          }]
        }, {
          label: '一级 2',
          children: [{
            label: '二级 2-1',
            children: [{
              label: '三级 2-1-1'
            }]
          }, {
            label: '二级 2-2',
            children: [{
              label: '三级 2-2-1'
            }]
          }]
        }, {
          label: '一级 3',
          children: [{
            label: '二级 3-1',
            children: [{
              label: '三级 3-1-1'
            }]
          }, {
            label: '二级 3-2',
            children: [{
              label: '三级 3-2-1'
            }]
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      };
    },
    methods: {
      handleNodeClick(data) {
        console.log(data);
      }
    }
  };
</script>

element tree remove 删除某个_加载


项目中需要做懒加载子树,每展开一次去加载当前节点的children

element tree remove 删除某个_加载_02


我用到的属性和方法

element tree remove 删除某个_加载_03


element tree remove 删除某个_加载_04


element tree remove 删除某个_子树_05


node-key我绑定的是,每个节点的唯一标识themeId

element tree remove 删除某个_前端_06


给el-tree加上ref,方便后续操作

element tree remove 删除某个_前端_07


element tree remove 删除某个_数据_08


element tree remove 删除某个_子树_09


根据自己的需要修改没有数据时展示的文本,默认为:暂无数据

element tree remove 删除某个_前端_10


修改后,当数据没有加载出来时,会显示自己设置的文字

element tree remove 删除某个_子树_11

element tree remove 删除某个_数据_12


我的基本配置就是这些了

<div class="tree-container">
        <el-tree
          lazy
          show-checkbox
          node-key="themeId"
          :load="loadNode"
          ref="themeTree"
          :data="themeTreeData"
          :props="defaultProps"
          empty-text="别急,正在加载数据"
          :check-strictly="true"
        >
        </el-tree>
      </div>

接下来到要处理逻辑的部分了,点击每个节点的展开按钮去加载子树,如果有子树数据,就继续展开,如果没有子树就显示复选框

element tree remove 删除某个_前端_13


加载子树的方法

loadNode(node, resolve) {
      if (node.level === 0) {
        //获取数据
        this.getTree(resolve);
      }
      if (node.level >= 1) {
        //加载子树
        this.getChildTree(node, resolve);
      }
    },

我的tree是在弹窗里面的,当我显示弹窗的时候,渲染tree的时候就会去自己调用一次loadNode这个方法,刚开始没有数据,我们看一下他传过来的初始参数node是什么样的

element tree remove 删除某个_子树_14


没有数据时node的level是0,后面的每一层的level都是递增的(第一层的node的level是1,第二层是2…)

所以才有了我们的逻辑(调用方法时将resolve传递过去,用于返回数据)

loadNode(node, resolve) {
      if (node.level === 0) {
        //获取数据
        this.getTree(resolve);
      }
      if (node.level >= 1) {
        //加载子树
        this.getChildTree(node, resolve);
      }
    },

getTree 第一次加载数据 将获取到的数据放到resolve里返回

getTree(resolve) {
      let param = {
        themeId: "753738c7-fa3d-11e6-b2a4-d4ae5278",
        themeType: "THEME",
      };
      getThemeTree(param).then((response) => {
        if (response.succ === "ok") {
          let data = response.result;
          resolve(data);
        }
      });
    },

getChildTree 每次点击展开图标去加载子数据 将获取到的数据放到resolve里返回

getChildTree(node, resolve) {
      let param = {
        themeId: node.data.themeId,
        themeType: "THEME",
      };
      getThemeTree(param).then((response) => {
        if (response.succ === "ok") {
          let data = response.result;
          resolve(data);
        }
      });
    },

对于样式的处理 如果某个节点是叶子节点(展开后没有子节点了)那么显示复选框可以选中,其余都不显示复选框(只有展开图标) 穿透样式可以是 /deep/ >>> ::v-deep

::v-deep .el-tree-node {
  .el-checkbox {
    display: none;
    .el-checkbox__inner {
      display: none;
    }
  }

  .is-leaf + .el-checkbox {
    display: inline-block;
    .el-checkbox__inner {
      display: inline-block;
    }
  }
}

element tree remove 删除某个_前端_15


如果不修改样式,因为设置了show-checkbox,每一个节点都会有复选框

element tree remove 删除某个_加载_16


以上就是关于我这次项目中用懒加载子树的所有逻辑了