Vue源码学习- Hook Event

Posted ~往无前

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue源码学习- Hook Event相关的知识,希望对你有一定的参考价值。

Hook Event (钩子事件),也就是生命周期钩子函数,供开发者在特定的逻辑点添加额外的处理逻辑,比如:在组件挂载阶段提供了beforeMount和mounted两个生命周期钩子,供开发者在组件挂载阶段执行额外的逻辑处理,比如为组件来准备渲染所需的数据。

callHook

/src/core/instance/lifecycle.js

/**
  * callHook(vm,'mounted')
  * 执行实例指定的生命周期钩子函数
  * 如果实例设置对应Hook Event ,比如:<comp @hook:mounted="method"/>,执行完生命周期函数之后,触发该事件的执行
*/
export function callHook(vm:Component, hook:string)
	//在执行生命周期钩子函数期间禁止收集依赖
	pushTarget()
	//从实例配置对象中获取指定钩子函数,比如mounted
	const hnalders = vm.$options[hook]
	//mounted hook
	const info = `$hook hook`
	if(handlers)
		//通过invokewithErrorHandler 执行生命周期钩子
		for(let i = 0,j=handlers.length;i<j;i++)
			invokeWithErrorHandling(hanlders[i],vm,null,vm,info)
		
	
	// HookEvent ,如果设置了Hook Event ,比如<comp @hook:mounted = 'method"/>则通过$emit触发该事件
	//vm._hasHookEvent 标识组件是否有hook event,这是在vm.$on中处理组件自定义事件时设置的
	if(vm._hasHookEvent)
		vm.$emit('hook:'+hook)
	
	//关闭依赖收集
	popTarget()

invokeWithErrorHanding

/src/core/util/error.js

/**
 * 通用函数,执行指定函数handler
 * 传递进来的函数会调用try catch包裹,进行异常捕获处理
*/
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
	
  • Hook Event 时如何实现的?
<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的实现原理;

以上是关于Vue源码学习- Hook Event的主要内容,如果未能解决你的问题,请参考以下文章

Vue源码之 $set

从 Event Loop 角度解读 Vue NextTick 源码

pg3 bypass源码阅读 —— 学习x64内核hook跳板技术

React的Effect Hook解决函数组件的性能问题和潜在bug!

Vue.js 源码学习笔记 -- 分析前准备 待续

Vue实例方法之事件的实现