序
一个问题干懵面试官第二弹:vue 声明周期。(PS:博客所涉及到的所有源码均基于 vue@3.2.37
版本)
第一弹链接 vue2 与 vue3 的区别
面试官问:你说下 vue 的生命周期吧
首先 vue2
和 vue3
的生命周期是有区别的:
Vue2 的生命周期主要是:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- Destoryed
而 vue3
在 vue2
的基础上进行了一些改变,主要是针对最后两个生命周期:
beforeDestroy -> beforeUnmount
Destoryed -> Unmounted
另外 options API
和 composition API
在生命周期上也有一些小的不同:
composition API
提供了setup
函数作为入口函数,替换了beforeCreate
和created
这两个生命周期钩子。所以在实际开发中,我们可以简单的把
setup
理解为created
进行使用。
在这 8
个常见的生命周期钩子中,我们最常用的就是 created
和 mounted
。
其中在 created
中,因为组件实例已经处理好了所有与状态相关的操作,所以我们可以在这里 获取数据、调用方法、watch
、computed
都可以。
而 mounted
主要是在 DOM
挂载之后被调用,所以如果我们想要获取 DOM
的话,那么需要在 mounted
之后进行。
除了这些之外,还有一些不太常见但是也比较有意义的,比如 beforeUpdate
、updated
。
其中 beforeUpdate
表示 数据变化后,视图改变前。updated
表示 数据变化后,视图改变后。
那么由这两个生命周期我们可以知道,vue
从数据变化到视图变化,其实是需要经历一定的时间的。原因是因为 vue
在内部通过 queue
队列的形式在更新视图(packages/runtime-core/src/scheduler.ts
):
这个逻辑还被体现在了 nextTick
这个方法上(packages/runtime-core/src/scheduler.ts
):
而这种更新本质上是一种异步的更新形式,因为这种异步更新形式(微任务)的存在,才导致出现 数据更新 -> 视图更新 出现延迟的原因。
因为它的异步更新是以微任务的形式呈现的,这也是为什么很多时候我们可以通过 setTimeout
代替 nextTick
的原因。
而如果从 vue
的源码中来看的话,整个组件的生命周期,其实是被分为两大部分的(packages/runtime-core/src/renderer.ts
):
isMounted
之前isMounted
之后
isMounted
之前表示:视图被挂载之前。因为组件的渲染本质上是 render
渲染了所有的 subVNode
,所以在 isMounted
之前,会得到一个 subTree
来进行渲染。
isMounted
之后表示:视图全部被渲染完成了,也就是 mounted
之后。着这个时候其实就是 beforeUpdate
和 updated
的活跃时期了。
总结
面试不易,珍惜每一次面试的机会,哪怕只增加一点成功的几率,那也是有价值的。
如果你想要了解更多有关源码的知识,那么可以查看我在慕课的课程 Vue3源码解析,打造自己的Vue3框架