preface
Hook Events are not used or even heard of by many Vue developers. After all, they are not mentioned in the official Vue documentation.
Vue provides lifecycle hook functions that allow developers to add additional processing logic at specific logical points. BeforeMount and Mounted lifecycle hooks allow developers to perform additional logical processing during the component mounting phase, such as preparing data for rendering the component.
What does this Hook Event have to do with Vue’s lifecycle Hook function? What good is it? That’s what this article is about.
The target
-
Understand what is a Hook Event? Understand the usage scenarios
-
In-depth understanding of the implementation principle of Hook Event
What is a Hook Event?
A Hook Event is a function that is implemented by Vue’s custom events combined with lifecycle hooks to inject additional lifecycle methods from outside the component.
Usage scenarios
Suppose you have a third party business component that simply calls the interface in the Mounted lifecycle to get the data and then renders the data to the page.
<template>
<div class="wrapper">
<ul>
<li v-for="item in arr" :key="JSON.stringify(item)">
{{ item }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
arr: []}},async mounted() {
// Call the interface to get the data rendered by the component
const { data: { data } } = await this.$axios.get('/api/getList')
this.arr.push(... data) } }</script>
Copy the code
Then I found some flaws in this component, such as the simplest, the interface wait time may be long, I want to output a loading in the console when the Mounted life cycle begins to execute. String to enhance user experience.
How can this requirement be implemented?
There are two ways: the first is more troublesome, modify the source; The second way is much simpler, which is to inject additional lifecycle methods from outside the component.
<template>
<div class="wrapper">
<comp @hook:mounted="hookMounted" />
</div>
</template>
<script>
// This is the third party business component above
import Comp from '@/components/Comp.vue'
export default {
components: {
Comp
},
methods: {
hookMounted() {
console.log('loading ... ')}}}</script>
Copy the code
If you refresh the page again, you will find that the business component requesting data will output loading… A string.
role
What is the function of Hook Event?
Hook Events allow you to inject additional lifecycle methods into a component from outside the component.
Realize the principle of
After knowing the use scenario and function of Hook Event, I will find its implementation principle from the source code, so as to “know the reason and know the reason”.
Hook events are defined by Vue in combination with the lifecycle Hook function, so let’s look at the lifecycle code. For example, we know that Vue’s lifecycle function is executed by a method called callHook
callHook
/src/core/instance/lifecycle.js
/** * callHook(VM, 'mounted') * if the instance has a Hook Event, for example, <comp@hookMounted ="method" /> < p style =" margin-top: 0px; margin-top: 0px@param {*} Vm component instance *@param {*} Hook lifecycle hook function */
export function callHook (vm: Component, hook: string) {
// Disallow dependency collection during lifecycle hook function execution
// #7573 disable dep collection when invoking lifecycle hooks
pushTarget()
// Retrieve the specified hook function from the instance configuration object, such as Mounted
const handlers = vm.$options[hook]
// mounted hook
const info = `${hook} hook`
if (handlers) {
// Execute the lifecycle hook via invokeWithErrorHandler
for (let i = 0, j = handlers.length; i < j; i++) {
invokeWithErrorHandling(handlers[i], vm, null, vm, info)
}
}
< com@hook :mounted="method" /> < com@hook :mounted="method" /> < com@hook :mounted="method" /
// vm._hashookEvent Identifies whether the component has a hook event, which is set when processing component custom events in vm.$on
if (vm._hasHookEvent) {
// vm.$emit('hook:mounted')
vm.$emit('hook:' + hook)
}
// Turn off dependency collection
popTarget()
}
Copy the code
invokeWithErrorHandling
/src/core/util/error.js
/** * this is a generic function that executes the specified function. ** This is a generic function that executes the specified function. ** This is a generic function
export function invokeWithErrorHandling (
handler: Function,
context: any,
args: null | any[],
vm: any,
info: string
) {
let res
try {
// Execute the handler function passed in and return the result
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)`))
// issue #9511
// avoid catch triggering multiple times when nested calls
res._handled = true}}catch (e) {
handleError(e, vm, info)
}
return res
}
Copy the code
vm.$on
/src/core/instance/events.js
/** * Listen for custom events on the instance, vm._event = {eventName: [fn1,... . } *@param {*} Event A single event name or an array of multiple event names *@param {*} Fn Callback function to execute when event is fired *@returns * /
Vue.prototype.$on = function (event: string | Array<string>, fn: Function) :Component {
const vm: Component = this
if (Array.isArray(event)) {
// If an event is an array of event names, then $on is called recursively through each of these events
for (let i = 0, l = event.length; i < l; i++) {
vm.$on(event[i], fn)
}
} else {
// Store registered events and callbacks as key-value pairs in the VM._event object VM._event = {eventName: [fn1,... }
(vm._events[event] || (vm._events[event] = [])).push(fn)
// hookEvent, which provides the opportunity to externally inject the declared cycle method into the component instance
// For example, inject extra logic to the component's Mounted method from outside the component
// This capability is implemented in combination with the Callhook method
if (hookRE.test(event)) {
vm._hasHookEvent = true}}return vm
}
Copy the code
conclusion
-
Interviewer: What is a Hook Event?
A:
A Hook Event is a function that is implemented by Vue’s custom events combined with lifecycle hooks to inject additional lifecycle methods from outside the component.
-
Interviewer: How can Hook Event be realized?
A:
<comp @hook:lifecycleMethod="method" /> Copy the code
-
When processing component custom events (vm.$on), if a component has a hook:xx Event (xx is the life cycle function of Vue), set VM._hashookEvent to true to indicate that the component has a hook Event
-
When the component lifecycle method is triggered, these lifecycle functions are internally executed by the callHook method. After the lifecycle function is executed, if vm._hashookEvent is found to be true, the current component hasHook events. $emit(‘hook:xx’) triggers the execution of the Hook Event
This is the implementation principle of Hook Event.
-
Form a complete set of video
(7) — Hook Event
Please focus on
Welcome everyone to follow my gold mining account and B station, if the content has to help you, welcome everyone to like, collect + attention
link
-
Vue source code interpretation (1) – preface
-
Vue source code interpretation (2) — Vue initialization process
-
Vue source code interpretation (3) – response principle
-
Vue source code interpretation (4) — asynchronous update
-
Vue source code Interpretation (5) — Global API
-
Vue source code interpretation (6) — instance method
-
(7) — Hook Event
-
Vue source code interpretation (8) — compiler parsing
-
Vue source code interpretation (9) — compiler optimization
-
Vue source code interpretation (10) — compiler generation rendering function
-
(11) — Render helper
-
Vue source code interpretation (12) — patch
Learning exchange group
link