vue的生命周期还是比较饶腾的,最直接的方法就是都写出来体验一下。
初体验
首先整理 vue3 的生命周期,只考虑在 setup 里面的就好。
import { // onBeforeCreate, // setup 中无效 // onCreated, // setup 中无效 onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered, onActivated, onDeactivated, provide, inject } from 'vue' export default (flag) => { // 在挂载开始之前被调用 onBeforeMount(() => { log(`${flag} == onBeforeMount`) }) // 在实例挂载完成后被调用 onMounted(() => { log(`${flag} == onMounted`) }) // 在数据发生改变后,DOM 被更新之前被调用 onBeforeUpdate(() => { log(`${flag} == onBeforeUpdate :`) }) // 在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用 onUpdated(() => { log(`${flag} == onUpdated`) }) // 在卸载组件实例之前调用 onBeforeUnmount(() => { log(`${flag} == onBeforeUnmount`) }) // 卸载组件实例后调用 onUnmounted(() => { log(`${flag} == onUnmounted`) }) // 在捕获一个来自后代组件的错误时被调用 onErrorCaptured((res) => { log(`${flag} == onErrorCaptured :`, res) }) // 跟踪虚拟 DOM 重新渲染时调用 onRenderTracked((res) => { log(`${flag} == onRenderTracked :`, res) }) // 当虚拟 DOM 重新渲染被触发时调用 onRenderTriggered((res) => { log(`${flag} == onRenderTriggered :`, res) }) // 被 keep-alive 缓存的组件激活时调用 onActivated((res) => { log(`${flag} == onActivated :`, res) }) // 被 keep-alive 缓存的组件失活时调用 onDeactivated((res) => { log(`${flag} == onDeactivated :`, res) }) }
- flag 做一个标识,区分不同的组件。
然后我们可以在组件里面引入
import { lifecycle } from '/nf-ui-core' lifecycle('表单页面', true)
这样就可以了。运行项目,可以看到组件的加载过程,更新过程,以及卸载过程。
增加功能
只是看看事件的触发情况,有点单调,我们可以加上一个计时的功能,看看加载、卸载、更新到底需要多长时间。
export default (flag, isTime = false) => { const t = (isTime) ? logTime(`${flag}***加载用时:`) : {end: () => {} } let t2 = null // 在实例挂载完成后被调用 onMounted(() => { log(`${flag} == onMounted`) t.end() })
- isTime 是否计时
如果需要计时的话,就加上计时功能,函数开始运行时记个时间,然后在 onMounted 里面再记个时间,然后相减就是加载的时间。
同理我们可以对卸载和更新计时
// 在数据发生改变后,DOM 被更新之前被调用 onBeforeUpdate(() => { log(`${flag} == onBeforeUpdate :`) if (isTime) { t2 = logTime(`${flag}***更新 DOM 用时`) } }) // 在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用 onUpdated(() => { log(`${flag} == onUpdated`) if (isTime) t2.end() }) // 在卸载组件实例之前调用 onBeforeUnmount(() => { log(`${flag} == onBeforeUnmount`) if (isTime) { t2 = logTime(`${flag}***卸载组件用时`) } }) // 卸载组件实例后调用 onUnmounted(() => { log(`${flag} == onUnmounted`) if (isTime) t2.end() })
计时采用的是 console.time()实现的,只是被我封装了一下。
然后运行组件就可以看到各个环节需要的时间了。
增加父子组件的关系。
组件是有父子关系的,而且有时候会比较复杂,虽然有了一个flag,但是并没有体现父子关系,简单的还好,复杂的就有点不清晰了。
我们可以利用 provide 、inject 来实现父子关系的表达。
const f = Symbol('___nf-liefcycle___') export default (_flag, isTime = false) => { // 判断上级的标识 const _parentflag = inject(f) const flag = (_parentflag) ? _parentflag + '----' + _flag : _flag // 记入标记 provide(f, flag) ... }
首先定义一个 Symbol 作为标志,然后看看上级组件是否有标记,没有的话就当做父组件,有的话就取出来,然后加上自己的flag,这样一个简单的父子的层级关系就做好了。
看看最终效果。
vue的生命周期
可以看到生命周期的钩子的触发过程,以及使用的时间,可以看看各个组件的渲染效率。