一个问题干懵面试官:说下 vue 的生命周期吧

11,431 阅读3分钟

一个问题干懵面试官第二弹:vue 声明周期。(PS:博客所涉及到的所有源码均基于 vue@3.2.37 版本)

第一弹链接 vue2 与 vue3 的区别

面试官问:你说下 vue 的生命周期吧

首先 vue2vue3 的生命周期是有区别的:

Vue2 的生命周期主要是:

  1. beforeCreate
  2. created
  3. beforeMount
  4. mounted
  5. beforeUpdate
  6. updated
  7. beforeDestroy
  8. Destoryed

vue3vue2 的基础上进行了一些改变,主要是针对最后两个生命周期:

beforeDestroy -> beforeUnmount

Destoryed -> Unmounted

另外 options APIcomposition API 在生命周期上也有一些小的不同:

composition API 提供了 setup 函数作为入口函数,替换了 beforeCreatecreated 这两个生命周期钩子。

所以在实际开发中,我们可以简单的把 setup 理解为 created 进行使用。

在这 8 个常见的生命周期钩子中,我们最常用的就是 createdmounted

其中在 created 中,因为组件实例已经处理好了所有与状态相关的操作,所以我们可以在这里 获取数据、调用方法、watchcomputed 都可以。

mounted 主要是在 DOM 挂载之后被调用,所以如果我们想要获取 DOM 的话,那么需要在 mounted 之后进行。

除了这些之外,还有一些不太常见但是也比较有意义的,比如 beforeUpdateupdated

其中 beforeUpdate 表示 数据变化后,视图改变前updated 表示 数据变化后,视图改变后

那么由这两个生命周期我们可以知道,vue 从数据变化到视图变化,其实是需要经历一定的时间的。原因是因为 vue 在内部通过 queue 队列的形式在更新视图(packages/runtime-core/src/scheduler.ts):

image-20230310141436004.png

这个逻辑还被体现在了 nextTick 这个方法上(packages/runtime-core/src/scheduler.ts):

image-20230310113338381.png

而这种更新本质上是一种异步的更新形式,因为这种异步更新形式(微任务)的存在,才导致出现 数据更新 -> 视图更新 出现延迟的原因。

image-20230310141758183.png

因为它的异步更新是以微任务的形式呈现的,这也是为什么很多时候我们可以通过 setTimeout 代替 nextTick 的原因。

而如果从 vue 的源码中来看的话,整个组件的生命周期,其实是被分为两大部分的(packages/runtime-core/src/renderer.ts):

  1. isMounted 之前
  2. isMounted 之后

image-20230310142123525.png

isMounted 之前表示:视图被挂载之前。因为组件的渲染本质上是 render 渲染了所有的 subVNode,所以在 isMounted 之前,会得到一个 subTree 来进行渲染。

image-20230310142500591.png

isMounted 之后表示:视图全部被渲染完成了,也就是 mounted 之后。着这个时候其实就是 beforeUpdateupdated 的活跃时期了。

总结

面试不易,珍惜每一次面试的机会,哪怕只增加一点成功的几率,那也是有价值的。

如果你想要了解更多有关源码的知识,那么可以查看我在慕课的课程 Vue3源码解析,打造自己的Vue3框架