Hook Event
什么是 Hook Event
Hook Event 是 Vue 的自定义事件结合生命周期钩子实现的一种从组件外部为组件注入额外生命周期方法的功能。
原理
callHook
Vue 的生命周期函数是通过一个叫 callHook
的方法来执行的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
export function callHook (vm: Component, hook: string) { pushTarget() const handlers = vm.$options[hook] const info = `${hook} hook` if (handlers) { for (let i = 0, j = handlers.length; i < j; i++) { invokeWithErrorHandling(handlers[i], vm, null, vm, info) } } if (vm._hasHookEvent) { vm.$emit('hook:' + hook) } popTarget() }
|
invokeWithErrorHandling
通用函数,这里用于执行生命周期钩子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
export function invokeWithErrorHandling ( handler: Function, context: any, args: null | any[], vm: any, info: string ) { let res try { res = args ? handler.apply(context, args) : handler.call(context) if (res && !res._isVue && isPromise(res) && !res._handled) { res.catch(e => handleError(e, vm, info + ` (Promise/async)`)) res._handled = true } } catch (e) { handleError(e, vm, info) } return res }
|
vm.$on
设置 vm._hasHookEvent,表示组件是否有 hook event,如果有的话,callHook 中会在生命周期钩子执行完毕后执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component { const vm: Component = this if (Array.isArray(event)) { for (let i = 0, l = event.length; i < l; i++) { vm.$on(event[i], fn) } } else { (vm._events[event] || (vm._events[event] = [])).push(fn) if (hookRE.test(event)) { vm._hasHookEvent = true } } return vm }
|
面试题
什么是 Hook Event?
Hook Event 是 Vue 的自定义事件结合生命周期钩子实现的一种从组件外部为组件注入额外生命周期方法的功能。
Hook Event 是如果实现的?
1
| <comp @hook:lifecycleMethod="method" />
|
- 处理组件自定义事件的时候(vm.$on) 如果发现组件有
hook:xx
格式的事件(xx 为 Vue 的生命周期函数),则将 vm._hasHookEvent
置为 true
,表示该组件有 Hook Event
- 在组件生命周期方法被触发的时候,内部会通过
callHook
方法来执行这些生命周期函数,在生命周期函数执行之后,如果发现 vm._hasHookEvent
为 true,则表示当前组件有 Hook Event,通过 vm.$emit('hook:xx')
触发 Hook Event 的执行
这就是 Hook Event 的实现原理。
参考
https://juejin.cn/post/6954923081462710309