1、方法一
使用$on和$emit
// Parent.vue <Child @mounted="doSomething"/> // Child.vue mounted() { this.$emit("mounted"); }
2、使用hook
// Parent.vue <Child @hook:mounted="doSomething" ></Child> doSomething() { console.log(‘父组件监听到 mounted 钩子函数 ...‘); }, // Child.vue mounted(){ console.log(‘子组件触发 mounted 钩子函数 ...‘); }, // 以上输出顺序为: // 子组件触发 mounted 钩子函数 ... // 父组件监听到 mounted 钩子函数 ...
hook的原理是:vue生命周期钩子函数
(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‘)
(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‘)
,注册的生命周期函数就会执行。
最后的最后:
添加钩子的方法有:
- 在
Vue
组件选项中添加; - 在模板中通过
@hooks:created
这种形式; vm.$on(‘hooks:created‘, cb)
或者vm.$once(‘hooks:created‘, cb)
。
原文地址:https://www.cnblogs.com/mengfangui/p/12546866.html
时间: 2024-09-28 10:16:49