Vue中onUpdated与nextTick的差异疑问及代码验证
Vue中onUpdated与nextTick的理解偏差纠正
我正在尝试理解Vue中onUpdated与nextTick的差异,为此编写了如下示例代码。根据Vue官方文档描述:
注册一个回调函数,会在组件因响应式状态变更而更新DOM树之后调用
我原以为这里的“DOM树”指虚拟DOM,虚拟DOM更新后就会调用onUpdated,此时真实DOM尚未更新,需用nextTick才能看到真实DOM变化。因此我预期handleClick、onBeforeUpdate和onUpdated中的输出内容一致,但实际输出不符,烦请纠正我的理解偏差。
代码
<template> <div> <button @click="handleClick">Insert/Remove</button> <div v-if="show" ref="content">I am an element</div> </div> </template> <script setup> import { reactive, ref} from 'vue' import { onBeforeMount,onMounted,onUpdated,onBeforeUpdate } from 'vue' const show = ref(true) const content = ref() const state = reactive({count: 0}) const handleClick = () => { show.value = !show.value console.log("handleClick:",show.value, content.value) // nextTick(() => { // // console.log(show.value, content.value) // }) } onMounted(()=>{ console.log("onMounted"); }) onBeforeUpdate(()=>{ console.log("onBeforeUpdate.show.value, content.value:",show.value, content.value) }) onUpdated(()=>{ console.log("onUpdated.show.value, content.value:",show.value, content.value) }) </script>
输出
//第一次点击Insert/Remove按钮后 handleClick: false <div>I am an element</div> App.vue:80 onBeforeUpdate.show.value, content.value: false <div>I am an element</div> App.vue:83 onUpdated.show.value, content.value: false null //第二次点击Insert/Remove按钮后 handleClick: true null App.vue:80 onBeforeUpdate.show.value, content.value: true null App.vue:83 onUpdated.show.value, content.value: true <div>I am an element</div>
核心理解纠正
onUpdated的触发时机:官方文档里的“DOM树”指的是真实DOM,而非虚拟DOM。
onUpdated会在组件的真实DOM完成更新后才触发,此时DOM已经和最新的响应式状态完全同步。输出逻辑解析:
- 第一次点击:
show.value被设为false,在handleClick和onBeforeUpdate阶段,Vue还未开始更新真实DOM,所以content.value依然指向原来的DOM元素;等到onUpdated触发时,真实DOM已经完成移除操作,content.value自然变为null。 - 第二次点击:
show.value设为true,handleClick和onBeforeUpdate阶段真实DOM还未渲染出目标元素,因此content.value是null;onUpdated触发时,真实DOM已经完成插入,content.value就指向了新生成的DOM元素。
- 第一次点击:
nextTick的定位:
nextTick的作用是在当前宏任务结束、真实DOM更新完成后执行回调。如果是在同步修改响应式状态后立刻想获取更新后的DOM(比如handleClick里),就需要用nextTick;但onUpdated本身已经在真实DOM更新后触发,所以在onUpdated中访问DOM时,不需要额外嵌套nextTick。
总结
onBeforeUpdate:响应式状态变更后,真实DOM更新前触发,此时DOM仍为旧状态。onUpdated:真实DOM更新后触发,此时DOM已是最新状态。nextTick:适用于任何需要等待DOM更新完成的场景,包括状态变更的同步代码后,不过在onUpdated中通常不需要使用。
内容的提问来源于stack exchange,提问作者Amrmsmb
相关产品推荐
相关产品推荐

