Vue监听子组件状态之巧用$nextTick

本文记录在Vue项目中使用elementUI的el-tree组件时遇到的数据回显问题及解决方案。作者在尝试回显用户选择过的部门数据到树形结构中时,发现即使数据正确,也无法达到预期的回显效果。通过使用$nextTick方法,确保DOM渲染完成后,再调用setCheckedNodes方法,成功解决了问题。
  • 背景

自己写了一个组件,这里就叫‘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)
})

 

Vue 3 中,`$nextTick` 方法仍然扮演着重要的角色,用于在数据更新后等待 DOM 完成渲染,然后执行特定的回调函数。它与 Vue 2 的行为基本一致,但在底层实现上有所变化。 ### 用法 在 Vue 3 中,`$nextTick` 可以通过组件实例访问,也可以作为全局方法使用。它的基本语法如下: ```javascript this.$nextTick(() => { // 在此可以安全地访问更新后的 DOM }); ``` 例如,在修改了响应式数据之后,如果需要操作更新后的 DOM 元素,就可以将相关代码放在 `$nextTick` 的回调中: ```vue <template> <div ref="content">{{ message }}</div> </template> <script> export default { data() { return { message: 'Hello Vue 3' }; }, methods: { updateMessage() { this.message = 'Updated Message'; this.$nextTick(() => { console.log(this.$refs.content.textContent); // 输出更新后的文本 }); } } }; </script> ``` ### 原理 Vue 3 使用 `Proxy` 实现了更高效的响应式系统,这使得 `Object.defineProperty` 的一些限制被克服,比如不能监听数组的变化和对象属性的新增或删除[^3]。当数据发生变化时,Vue 会将这些变更加入到一个异步更新队列中,而不是立即更新 DOM。这种机制有助于提高性能,因为多个数据变更可以合并成一次 DOM 更新。 `$nextTick` 的作用就是在这一系列的异步更新完成后执行指定的回调。这意味着当你调用 `$nextTick` 并传递一个回调函数时,这个回调会在所有因最近的数据变更而引起的 DOM 更新完成之后被执行。 具体来说,当数据改变时,Vue.js 会触发依赖收集过程,并通过 `Dep`(依赖管理器)来通知相关的 `watcher`。这些 `watcher` 会将它们的回调放入一个异步更新队列中。一旦当前事件循环中的所有数据变更都处理完毕,Vue 就会清空这个队列,并运行每个 `watcher` 的回调。只有在这整个过程中,DOM 已经根据最新的数据进行了更新,这时 `$nextTick` 的回调才会被调用[^2]。 因此,`$nextTick` 是确保在 DOM 更新后执行代码的有效方式,这对于需要基于最新 DOM 状态进行操作的场景非常有用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值