vue首次渲染完整时间线

34 阅读2分钟

错误的预判: watch(immediate)只有在openDialog事件执行之后,v-model变为true的时候才会执行回调。

一、watch(immediate)的执行时机

阶段发生的事
setup创建响应式、watch、computed
watch(immediate)就在 setup 过程中执行
render读取 template 表达式
beforeMount准备挂载
mountedDOM 已经插入

👉 watch(immediate) 比 render 还早

所以:

  • 不受 v-if 影响
  • 也不等 DOM

下面的行为都不受组件内部的v-if的影响

行为执行阶段
watch(immediate)setup
模板中 {{ xxx }} 被访问render 阶段
v-for source 被读取render 阶段

二、组件内部的v-if和组件外部的v-if的本质区别

情况 A:v-if 在组件外部(控制组件是否存在)

<Child v-if="show" />

show === false 时:

项目是否发生
创建组件实例
执行 setup
注册 watch
render template
读取任何表达式

👉 Child 在运行期完全不存在

情况 B:v-if 在组件内部(控制局部渲染)

<template>
  <div v-if="show">
    {{ foo }}
  </div>
</template>

show === false 时:

项目是否发生
创建组件实例
执行 setup
watch(immediate)
render() 调用
读取 foo❌(因为分支不走)

👉 组件存在,但该分支在 render 中被跳过

结论

  • 外部的v-if,整个组件的实例都不存在,setup阶段都不会执行
  • 内部的v-if, 只有v-if的部分的render不会执行,其余的操作都会执行。

vue首次渲染

Vue 3 组件首次渲染完整时间线

顺序官方钩子 / 阶段发生的事
1setup初始化状态、注册 watch / computed
2watch(immediate)在 setup 执行期间立即触发
3render(内部)执行 render 函数,读取 template 表达式
4onBeforeMountDOM 挂载前
5mount(内部过程)创建并插入真实 DOM
6onMountedDOM 已插入页面

👉 这里的「mount」是内部过程,不是钩子