【Element-ui 】el-tree 树 异步加载

1、起因

全网找了很多相关资料,写的都不是很明白,需要一定的摸索,尽管有着10年开发经验的我,还是很看不惯,还是自己写一个吧!

2、思路

1.用el-tree

2.用lazy 和 load 来做异步

3.要有初始化(很多人不写这一步,导致一头雾水)

3、实践

1.先上代码(本人项目真实代码)

          <!-- 
            ref:相当于html的ID
            props:数据转换(如果你接口返回的数据格式和el-tree 要求的格式不一致时,用这个,否则不用)( :props="props" )
            load:加载子树数据的【这是一个方法】,仅当 lazy 属性为true 时生效。
            lazy:是否懒加载子节点,需与 load 方法结合使用。
            node-key:是所有节点之前的唯一标识(在这里设置节点的唯一键)
            highlight-current:点击时是否高亮显示
            @node-click:点击事件,每次点击节点是都会触发,返回当前节点的node
            default-expanded-keys:默认展开节点数组,从第一个根节点到最后展开节点的id,例如这样:[1, 2, 12]         
          -->
          <el-tree ref="tree" 
:data="treeData"
:props="treeProps" 
node-key="value" 
lazy :load="loadNode" 
:highlight-current="true" 
@node-click="treeClick" 
:default-expanded-keys="expandIds" 
:filter-node-method="treeFilterNode" >
          </el-tree>


export default {
data: () => ({
    treeProps: {//树的配置选项
      children: 'children',
      label: 'label',
      isLeaf: 'isLeaf'
    },
    treeData: [], //树的全部数据
    expandIds: [],//默认树节点展开IDs
    treeFilterText: '',

  }),
  methods: {
    //14.获取节点数据
    async getTreeData(node, resolve, isFirst = false) {
      let fid = 0
      if (!isFirst) {
        fid = node.data.value
      }
      this.showGrouploading = true;
      const res = await this.$API.system.dept.viewerasyn.get(fid);
      this.showGrouploading = false;
      if (res.data.length > 0) {
        if (isFirst) {
          _.forEach(res.data, item => {
            if (item.children === null) {
              item.children = [];
            }
            // (指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效)
            // isLeaf 为true时,是叶子节点,false时非叶子节点
            item.isLeaf = !item.children || item.children.length === 0;
            //this.expandIds.push(item.value)
          });
          let def = res.data[0].value
          this.formData.FDepartID = def
          this.getCustomGrade(def)
          this.getRole(def)
          this.getData()
          this.treeData = res.data;
          //渲染
          resolve(this.treeData);
          //设置默认展开
          this.expandIds.push(def);
          // 这一步为了懒加载中等节点渲染完毕后点击到我们需要的节点上去
          // 通过 key 设置某个节点的当前选中状态,使用此方法必须设置 node-key  属性
          // this.$refs.tree.setCurrentKey(def);
        } else {
          _.forEach(res.data, item => {
            if (item.children === null) {
              item.children = [];
            }
            // (指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效)
            //isLeaf 为true时,是叶子节点,false时非叶子节点
            item.isLeaf = !item.children || item.children.length === 0;
            item.children = [];
          });
          node.data.children = res.data;
          //渲染
          resolve(res.data);
        }
      }
    },
    //15.异步树叶子节点懒加载逻辑(返回当前节点的数据,渲染节点数(用来获取到节点数据后渲染使用的))
    //第一个是树节点对象,第二个是一个解析函数resolve,你需要在数据加载完成后调用它,并传入子节点数据。
    //树渲染完成后自动加载一次。
    async loadNode(node, resolve) {
      let isFirst = false
      //一级节点处理(根节点)
      if (node.level === 0) {
        //这里也可以写两个方法分别请求数据。
        isFirst = true
      } else {
        // 其余节点处理
        console.log(node)
        isFirst = false
      }
      await this.getTreeData(node, resolve, isFirst);
    },
    //16.树点击事件
    treeClick(data, node) {
      //console.log('data', data, node);
      this.nodeId = node.data.value;
      this.formData.FDepartID = data.value
      this.upsearch()
    },
}

2.代码讲解

1.html部分

里面有注释

2.过程(核心)

2.1 数据量太大,请求卡,前端渲染时间漫长,用懒加载其实就是(吃多少,装多少),点击树枝,才会加载叶子,而不是直接给一棵树。

2.2 loadNode方法,在页面加载完成后会主动调用一次,也就是说:data="treeData"这个方法会自动运行一次 ,其实treeData为[]时,它的level=0,并且 data是空对象{}。如图:

有的人不写treeData,也是可以的,就是方法【14】里面渲染的时候写正确,其实到了这里就是请求数据会来了,第一次请求和第n次请求只是后端的处理而已。

我的代码有一点不好的是,后端没有isLeaf,是否是子级,所以要前端去处理,数据库设计的不合理导致的,不然代码看起来不会那么长,我的业务逻辑也写在了代码里,没有去掉。

2.3 一定要写isLeaf,还有树的配置,否则可能显示不出叶子来【切记】。

    treeProps: {//树的配置选项

      children: 'children',

      label: 'label',

      isLeaf: 'isLeaf'

    },

2.4我想要进页面默认展示1.2级,只有一级就一个,还要去点击,不合理,用expandIds来设置默认展开。(就像下图这样,第一级和第二级展开,其实就是望果总部展开,后续的不需要再去追加了,好像这个组件自己会运作,只是首次需要设置)没有过多验证这块!!!

3.后端接口返回格式


    /// <summary>
    /// Int 树形选择器(element)
    /// </summary>
    public class SelectorIntDto
    {
        /// <summary>
        /// 显示
        /// </summary>
        public string label { get; set; }

        /// <summary>
        /// 值(注意这个在前端需要转换)也就是:props
        /// </summary>
        public int value { get; set; }

        /// <summary>
        /// 父级ID (本人项目自用)
        /// </summary>
        public int parentId { get; set; }

        /// <summary>
        /// 子集
        /// </summary>
        public List<SelectorIntDto> children { get; set; }
    }

4、总结

大概这些,代码里也是满满的注释,老板喊我去搬砖了。

element-plus 是一个基于 Vue.jsUI 组件库,el-tree-select 是其中的一个组件,用于实现形结构的下拉选择。 el-tree-select 组件是在 el-select 组件的基础上进行扩展,使其支持形结构的数据。使用 el-tree-select,我们可以在下拉列表中展示状数据,并支持选择节点的功能。 el-tree-select 的使用方式大致分为以下几步: 1. 引入 element-plus 库,确保已安装并正确引入相关 CSS 和 JS 文件。 2. 在组件中使用 el-tree-select 标签,通过 v-model 绑定选中的节点,将选中的节点值赋给 data 中的一个变量。 3. 设置 el-tree-select 的配置项,包括数据源、显示字段、样式等。 4. 响应选择事件,在 el-tree-select 标签上绑定 change 事件,根据选中的节点进行相应操作。 配置项中常用的属性有: - data:形数据源,可以是一个数组或者通过异步加载数据。 - label-prop:用于显示节点文本的属性名。 - value-prop:用于取值的属性名。 - default-expand-all:是否默认展开全部节点。 - filterable:是否支持输入框搜索。 el-tree-select 还提供了其他的配置项和方法,可以根据具体需求进行调整和使用。 总之,element-plus 的 el-tree-select 组件提供了一种简单易用的方式来展示和选择形数据,在Vue.js项目中非常实用。通过合理配置,我们可以灵活定制形下拉选择框的功能和样式,使其符合项目的需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值