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,这样一个简单的父子的层级关系就做好了。
看看最终效果。

可以看到生命周期的钩子的触发过程,以及使用的时间,可以看看各个组件的渲染效率。
网友评论