antd-vue树形控件实现默认展开全部节点

antd-vue树形控件实现默认展开全部节点

树形控件官方文档

版本信息:

	"vue""2.6.11"
	"ant-design-vue": "1.7.0"
	"vuex": "3.1.1"

背景

在做项目的时候遇到需要默认选中和展开所有节点的需求。

  • 自动选中所有节点
    a-treev-model默认就是checkedKeys,因此默认选中所有节点(父节点和子节点),只要在created周期钩子里将checkedKeys初始化成所有子节点就好了。
  • 自动展开所有节点:
    defaultExpandAll这个属性似乎无效,于是乎尝试在created周期里初始化defaultExpandedKeys为所有节点。

于是乎html部分这样写

...
    <a-spin :spinning="treeOnLoad" style="height:200px;">
      <a-tree
        v-model="checkedKeys"
        checkable
        :tree-data="teamTreeWithCarCount"
        :defaultExpandedKeys="expandedKeys"
      />
    </a-spin>
...

js部分的created周期函数这样写:

  async created () {
  	...
  	// 树的获取
    await this.getTeamTreeWithCarCount() // 获取树节点信息的函数
    this.checkedKeys = this.teamTreeList // this.teamList在computed中将树节点平铺开而成
    this.defaultExpandedKeys = this.teamTreeList // 默认展开全部节点
    this.treeOnLoad = false
    ...
  }

结果并没有自动展开…
在这里插入图片描述

分析

  • 首先分析生命周期问题:
    父组件(即当前组件,称为A),子组件(a-tree组件,称为B)。
    B作为A的子组件,执行顺序应该为:A beforeCreate
    -> A created,此时A的props,methods, data 和 computed 都初始化完毕,然后在A created生命周期,发送获取树节点的axios请求。这之后编译好模板字符串,进入A beforeMount,挂载过程中发现需要渲染子组件,然后进行子组件的构建:B beforeCreateB created,B beforeMountB mounted,等待所有子组件加载完毕,进入A mounted
    总结一下,就是A beforeCreate->A created->A beforeMount->B beforeCreate-> B created-> B beforeMount-> B mounted-> A mounted
    按照这个逻辑,会有两个问题:
  1. B mountedA created之后,那么A中的expandedKeys应该会被渲染进B的defaultExpandedKeys里呀?
  2. 就算在B mounted结束之后,B中的defaultExpandedKeys还没有得到正确的数据,那么后续A中的expandedKeys拿到了,难道不会触发B beforeUpdate生命周期么?那这样还是会展开所有的节点呀?
  • 生命周期钩子的异步
    针对第一个问题,需要弄明白一个概念,生命周期钩子本质上是函数,如果把它写成async函数,它就成了异步函数,它是不会阻塞后面生命周期的执行的。
    A created为例,在这个生命周期函数里,我们执行了这个语句:
    await this.getTeamTreeWithCarCount() // 获取树节点信息的函数
    但这个await语句只会阻塞created函数内后续语句的执行,不应该created函数外部同步语句的执行,也就是不阻塞vue后续的生命周期的进行。
    所以,当A beforeCreate->A created->A beforeMount->B beforeCreate-> B created-> B beforeMount-> B mounted-> A mounted这个流程走完之后,axios异步返回的结果才会作用到页面上,引发A beforeUpdate->B beforeUpdate->B updated->A updated
    至此就解释了为什么子组件B直到mounted阶段都不会被父组件Aaxios返回的数据初始化。

  • defaultExpandedKeys 本身就是一锤子买卖
    针对第二个问题,后续返回的树节点数据为什么不会被更新到子组件A的defaultExpandedKeys上呢?这是因为defaultExpandedKeys的设计初衷本就不是动态变化的,可以看下官方的示例:
    在这里插入图片描述
    default字样的属性本身就是写死的,或者严谨点,匿名变量,而不是一个可更改的变量
    因此,defaultExpandedKeys在初始化之后,再去更改它是没有作用的。

解决方案

可以通过完全操控a-treeexpandedKeys来实现默认全部展开的效果。
html代码如下:

        <a-spin :spinning="treeOnLoad" style="height:200px;">
          <a-tree
            v-model="checkedKeys"
            checkable
            :defaultExpandParent="true"
            :tree-data="teamTreeWithCarCount"
            :expandedKeys.sync="defaultExpandedKeys"
            :defaultExpandAll="true"
          />
        </a-spin>

注意expandedKeys需要使用.sync修饰符,否则子组件a-tree无法修改defaultExpandedKeys,就无法进行正常的勾选了。
然后在JS部分还是一样:

  async created () {
  	...
  	// 树的获取
    await this.getTeamTreeWithCarCount() // 获取树节点信息的函数
    this.checkedKeys = this.teamTreeList // this.teamList在computed中将树节点平铺开而成
    this.defaultExpandedKeys = this.teamTreeList // 默认展开全部节点
    this.treeOnLoad = false
    ...
  }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

JohnKeatinghhh

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值