-
背景
自己写了一个组件,这里就叫‘my’。在‘my’组件中使用了elementUI的树形组件‘el-tree’。此情况下,my为父组件,el-tree为子组件。
-
需求
我有两个集合数据。1.所有部门数据;2.用户选择过的部门数据。两个集合,集合内对象的结构一样。【所有部门数据】要在el-tree进行展示,在此基础上,回显【用户选择过的部门数据】(即选择过的部门默认打上勾勾)。效果如下:
-
遇到问题
情况概括:【所有部门数据】与【用户选择过的部门数据】是同时拿到的,没有先后之分。
问题描述:el-tree属性node-key的值为部门对象的id(dept.id),我使用el-tree的setCheckedNodes方法进行数据回显。经检查,数据没有问题,【用户选择过的部门数据】内的id值与【所有部门数据】内的id值可以进行匹配。但是,达不到回显效果。
-
问题推断
Vue通过数据渲染出来的节点都是虚拟的,简单概括,Vue的节点随着数据变化而变化。有A数据就有A的DOM节点。上面说到,同时拿到【所有部门数据】与【用户选择过的部门数据】。当【所有部门数据】拿到时就交给了el-tree去做渲染,但是紧接着又拿【用户选择过的部门数据】作为参数传递调用el-tree的setCheckedNodes方法。代码如下:
this.deptList = [...]
this.deptSelectedList = [...]
this.$refs.deptTree.setCheckedNodes(this.deptSelectedList)
此时,忽略了一个问题。el-tree究竟有没有渲染好?没有渲染好,那么相应的DOM节点就不会产生,没有产生的相应的DOM节点就无法进行操作(打勾勾)。
渲染是异步操作,JS不会得到渲染结果后才会继续执行。但是在此情景下,JS必须等待渲染结果后才能继续执行。所以,需要$nextTick。$nextTick具体看官网介绍,本篇只记录一个解决问题的技巧。
-
问题解决
this.deptList = [...]
this.deptSelectedList = [...]
this.$nextTick(() => {
this.$refs.deptTree.setCheckedNodes(this.deptSelectedList)
})