vue 父组件监听子组件生命周期
一、生命周期
生命周期是指vue实例从创建到销毁所经历的一系列过程。vue官网生命周期如下图所示:
上图一共描述了8个生命周期钩子函数,即:
'beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeUpdate', 'updated', 'beforeDestroy', 'destroyed',
思考一个问题,vue实例中一共就这8个生命周期钩子函数吗?
答案是,vue生命周期钩子函数不止这8个。
(1)动态组件钩子函数
vue实例若是动态组件(即keep-alive)时,还有2个钩子函数:
'activated',
'deactivated',
(2)errorCaptured
errorCaptured是vue 2.5.0版本新增的一个钩子函数,它主要用来捕获一个来自子孙组件的错误,即可以应用在前端监控中。
结论:vue一共有11个说明周期钩子函数。
二、父组件如何监听子组件生命周期钩子函数
1、使用$on和$emit
子组件$emit触发一个事件,父组件$on监听相应事件。
// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
}
2、hook钩子函数
使用vue hook生命周期钩子函数。
// Parent.vue
<Child @hook:mounted="doSomething" ></Child>
doSomething() {
console.log('父组件监听到 mounted 钩子函数 ...');
},
// Child.vue
mounted(){
console.log('子组件触发 mounted 钩子函数 ...');
},
// 以上输出顺序为:
// 子组件触发 mounted 钩子函数 ...
// 父组件监听到 mounted 钩子函数 ...
下面阐述vue hook生命周期原理:
(1)vue源码生命周期描述
vm._self = vm
initLifecycle(vm) // 初始化生命周期
initEvents(vm) // 初始化事件
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
即生命周期钩子函数(如beforeCreate、created等)都会调用callHook函数。
(2)callHook函数源码
export function callHook (vm: Component, hook: string) {
// #7573 disable dep collection when invoking lifecycle hooks
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()
}
即每个生命周期钩子函数执行函数为:vm.$emit('hook:' + hook),前提条件是_hasHookEvent值为true。
(3)_hasHookEvent标志位源码
const hookRE = /^hook:/ // 以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++) {
vm.$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
}
当使用了$on
方法监听事件时,如果事件名以 hooks:
作为前缀,那么这个事件会被当做hookEvent
,注册事件回调的同时,vm._hasHookEvent
会被置为true
。当使用callHook
调用生命周期函数时,由于_hasHookEvent
为true
,所以会$emit('hooks:xxx')
,注册的生命周期函数就会执行。
三、生命周期钩子函数调用方法汇总
(1)在Vue
组件选项中添加钩子函数
<script> export default { components: {}, data () { return { } }, computed: { }, created () { }, mounted () { }, beforeDestroy () {} } </script>
(2)在模板中添加@hooks:created
// Parent.vue <Child @hook:mounted="doSomething" ></Child>
(3)js代码
vm.$on('hooks:created', cb); vm.$once('hooks:created', cb);//只执行一次
作者:孟繁贵 Email:meng010387@126.com 期待共同进步!