antd-vue树形控件实现默认展开全部节点
antd-vue树形控件实现默认展开全部节点
- 背景
- 分析
- 解决方案
树形控件官方文档
版本信息:
"vue":"2.6.11""ant-design-vue": "1.7.0""vuex": "3.1.1"
背景
在做项目的时候遇到需要默认选中和展开所有节点的需求。
- 自动选中所有节点
a-tree的v-model默认就是checkedKeys,因此默认选中所有节点(父节点和子节点),只要在created周期钩子里将checkedKeys初始化成所有子节点就好了。 - 自动展开所有节点:
defaultExpandAll这个属性似乎无效,于是乎尝试在created周期里初始化defaultExpandedKeys为所有节点。
于是乎html部分这样写
...<a-spin :spinning="treeOnLoad" style="height:200px;"><a-treev-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 beforeCreate,B created,B beforeMount,B mounted,等待所有子组件加载完毕,进入A mounted。
总结一下,就是A beforeCreate->A created->A beforeMount->B beforeCreate->B created->B beforeMount->B mounted->A mounted。
按照这个逻辑,会有两个问题:
B mounted在A created之后,那么A中的expandedKeys应该会被渲染进B的defaultExpandedKeys里呀?- 就算在
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-tree的expandedKeys来实现默认全部展开的效果。
html代码如下:
<a-spin :spinning="treeOnLoad" style="height:200px;"><a-treev-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...}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
