代码运行结果
代码示例
<div id="app"></div>
<script>
let {
createApp,
reactive,
Fragment,
toRefs,
h,
getCurrentInstance,
provide,
inject,
onMounted
} = Vue
const MyCpn = {
setup(props, { emit, slots }) {
const state = inject('state')
return () => h('div', null, [state.count])
}
}
const App = {
setup() {
const state = reactive({ count: 0 })
provide('state', state)
onMounted(() => {
setTimeout(() => {
state.count++
}, 2000)
})
},
render() {
return h(MyCpn, null)
}
}
createApp(App).mount('#app')
</script>
第一:调用 onMounted 生命周期函数,实际上是调用了 createHook 函数,并通过枚举类型,传入生命周期的 type。
export const onBeforeMount = createHook(LifecycleHooks.BEFORE_MOUNT)
export const onMounted = createHook(LifecycleHooks.MOUNTED)
export const onBeforeUpdate = createHook(LifecycleHooks.BEFORE_UPDATE)
export const onUpdated = createHook(LifecycleHooks.UPDATED)
export const onBeforeUnmount = createHook(LifecycleHooks.BEFORE_UNMOUNT)
export const onUnmounted = createHook(LifecycleHooks.UNMOUNTED)
export const onServerPrefetch = createHook(LifecycleHooks.SERVER_PREFETCH)
生命周期 枚举类型的 type, 就是首字母的缩写
export const enum LifecycleHooks {
BEFORE_CREATE = 'bc',
CREATED = 'c',
BEFORE_MOUNT = 'bm',
MOUNTED = 'm',
BEFORE_UPDATE = 'bu',
UPDATED = 'u',
BEFORE_UNMOUNT = 'bum',
UNMOUNTED = 'um',
DEACTIVATED = 'da',
ACTIVATED = 'a',
RENDER_TRIGGERED = 'rtg',
RENDER_TRACKED = 'rtc',
ERROR_CAPTURED = 'ec',
SERVER_PREFETCH = 'sp'
}
第二:在 createHook 函数中,返回生命周期钩子函数,我们组件当中调用的生命周期函数就是 createHook 返回的这个函数。
export const createHook =
<T extends Function = () => any>(lifecycle: LifecycleHooks) =>
(hook: T, target: ComponentInternalInstance | null = currentInstance) =>
// post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
(!isInSSRComponentSetup || lifecycle === LifecycleHooks.SERVER_PREFETCH) &&
injectHook(lifecycle, (...args: unknown[]) => hook(...args), target)
第三:传入钩子 hook 和 当前组件实例,调用 injectHook 函数。
第四:在 injectHook 函数中,将生命周期函数,加入到组件实例对应的生命周期队列当中去。
{
m: [() => {}, () => {}],
u: [() => {}, () => {}]
}
export function injectHook(
type: LifecycleHooks,
hook: Function & { __weh?: Function },
target: ComponentInternalInstance | null = currentInstance,
prepend: boolean = false
): Function | undefined {
if (target) {
const hooks = target[type] || (target[type] = [])
// cache the error handling wrapper for injected hooks so the same hook
if (prepend) {
hooks.unshift(wrappedHook)
} else {
hooks.push(wrappedHook)
}
return wrappedHook
}
}
最后就是将这些生命周期的钩子函数,在组件挂载和更新的阶段进行调用了。