最佳實踐:vue2 父元件監聽子元件生命週期鉤子
阿新 • • 發佈:2020-12-27
技術標籤:VuevueHookEvent父元件監聽子元件生命週期鉤子hooksvue最佳實踐
HookEvent
原始碼地址:https://github.com/vuejs/vue/blob/master/src/core/instance/lifecycle.js#L314
export function callHook (vm: Component, hook: string) {
const handlers = vm.$options[hook]
if (handlers) {
for (let i = 0, j = handlers.length; i < j; i++) {
try {
handlers[i].call(vm)
} catch (e) {
handleError(e, vm, `${hook} hook`)
}
}
}
if (vm._hasHookEvent) {
vm.$emit('hook:' + hook)
}
}
- 對外的生命週期函式需要主動捕獲其過程發生的錯誤,避免整個Vue例項生成過程終止
- 生命週期函式存放位置
const handlers = vm.$options[hook]
- 可以通過
$on
進行監聽事件vm.$emit('hook:' + hook)
vm._hasHookEvent
- 初始化事件相關
initEvents
函式中賦值為 false - 事件註冊例項方法
$on
中賦值為 true callHoook
函式中判斷_hasHookEvent
是否為true
原始碼地址:https://github.com/vuejs/vue/blob/master/src/core/instance/events.js#L52
export function eventsMixin (Vue: Class<Component>) {
const hookRE = /^hook:/
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++) {
this.$on(event[i], fn)
}
} else {
(vm._events[event] || (vm._events[event] = [])).push(fn)
// optimize hook:event cost by using a boolean flag marked at registration
// instead of a hash lookup
if (hookRE.test(event)) {
vm._hasHookEvent = true
}
}
return vm
}
const hookRE = /^hook:/
註冊事件以 hook:
開頭
實現方式
常規方式
子元件修改;
mounted() {
this.$emit("mounted");
}
父元件中呼叫:
<Child @mounted="doSomething"></Child>
缺點: 需要修改子元件原始碼,增加相關 $emit
事件
$options方式
通過 refs 獲取相關元件例項,然後增加相應的 lifecycle hook
mounted () {
const HelloWorldVmOption = this.$refs['HelloWorldRef'].$options
if (!HelloWorldVmOption['updated']) HelloWorldVmOption['updated'] = []
HelloWorldVmOption['updated'].push(() => {
...
})
}
缺點: 由於 refs 只能在 mounted 及以後的生命週期中獲取,因此這種方式只能監聽子元件 mounted
以後的 lifecycle hook。
@hook:event
<Child @hook:mounted="doSomething"></Child>
在 vue2 中,完美解決!不需要修改原始碼~~