This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money
What is the Vue life cycle? Why are you still asking me this stupid street question?
- Test your proficiency
- Measure your depth
- Examine your knowledge
Some of you can name the following hook functions, and some of you can’t even name these hook functions, which really needs to be added, because these hook functions are only the tip of the iceberg of the full Vue life cycle
Source code address: SRC /shared/ constants.js-9 line
export const LIFECYCLE_HOOKS = [
'beforeCreate'.'created'.'beforeMount'.'mounted'.'beforeUpdate'.'updated'.'beforeDestroy'.'destroyed'.'activated'.'deactivated'.'errorCaptured'.'serverPrefetch'
]
Copy the code
The full life cycle of Vue can be roughly divided into four phases
- Initialization phase: Initializes some events, attributes, and reactive data for the Vue instance
- Template compilation phase: put what we wrote
<template></template>
Templates are compiled into rendering functionsrender
- Mount phase: Render templates to real DOM nodes and perform updates when data changes
- Destruction phase: Removes the component instance from the parent component and cancels dependency and event listening
How are these four stages divided? Here is a picture (from Vue Chinese community).
The hook function is called at the end of each lifecycle. The hook function is called at the end of each lifecycle
Initialization phase
new Vue()
The first thing we do in this phase is create a Vue instance object with new
new Vue({
el:'#app',
store,
router,
render: h= > h(App)
})
Copy the code
If you can use new there must be a constructor, so let’s see
Source address: SRC/core/instance/index, js – 8
function Vue (options) {
if(process.env.NODE_ENV ! = ='production' && !(this instanceof Vue) ) {
warn('Vue is a constructor and should be called with the `new` keyword')}this._init(options)
}
initMixin(Vue)
Copy the code
So the key to new Vue() is _init(), so let’s see where it comes from and what it does
_init()
Source address: SRC/core/instance/init. Js – 15 lines
I’ve left out a little bit of environmental judgment, and the main process is this
- Merge configuration, mainly to put some built-in components
<component/>
,<keep-alive>
,<transition>
,directive
,filter
The list of hook function names from the beginning of this article is merged into vue. options - I’m calling some initialization functions, and what exactly is being initialized here I wrote down in the comments
- Triggers the lifecycle hook,
beforeCreate
和created
- The last call
$mount
Mount to the next stage
export function initMixin (Vue: Class<Component>) {
// Add the _init method to the prototype
Vue.prototype._init = function (options? :Object) {
// Save the current instance
const vm: Component = this
// Merge the configuration
if (options && options._isComponent) {
// Mount the functions and listeners of the parent component to options and specify $options for the component
initInternalComponent(vm, options)
} else {
// Merge the options we passed in with the current constructor and the parent options and mount it to the prototype
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
vm._self = vm
initLifecycle(vm) $parent, $children, $refs, $root, _watcher... Etc.
initEvents(vm) // Initialize events: $on, $off, $emit, $once
initRender(vm) // Initialize render: render, mixin
callHook(vm, 'beforeCreate') // Call the lifecycle hook function
initInjections(vm) // Initialize inject
initState(vm) // Initialize component data: props, data, methods, watch, computed
initProvide(vm) // initialize provide
callHook(vm, 'created') // Call the lifecycle hook function
if (vm.$options.el) {
// If el is passed, $mount will be called to enter the template compilation and mount phase
// If not, you need to manually execute $mount to proceed to the next stage
vm.$mount(vm.$options.el)
}
}
}
Copy the code
Remember what configuration was merged, what was initialized, when the two lifecycle hook functions were called, and then $mount was called to proceed to the next phase
Template compilation stage
So let’s look at the picture and see what we’re doing at this stage
$mount()
Dist/vue.js-11927
Vue.prototype.$mount = function ( el, hydrating ) {
el = el && query(el);
var options = this.$options;
// If there is no render
if(! options.render) {var template = options.template;
// check if there is a template
if (template) {
if (typeof template === 'string') {
if (template.charAt(0) = = =The '#') { template = idToTemplate(template); }}else if (template.nodeType) {
template = template.innerHTML;
} else {
return this
}
// If there is el
} else if(el) { template = getOuterHTML(el); }}return mount.call(this, el, hydrating)
};
Copy the code
$mount = $mount = $mount = $mount = $mount = $mount = $mount = $mount = $mount = $mount
<div id='app'>
<p>{{ name }}</p>
</div>
<script>
new Vue({
el:'#app'.data: {name:'MuHua' },
template:'< div > Denver < / div >'.render(h){
return h('div', {}, 'Good good study, day day up')}})</script>
Copy the code
This might be a little awkward, but imagine what happens when you execute code like the one above
Because the source code is the first to determine whether render exists, if so, directly use the render function
If not, then template and EL, if template is present, then el is ignored
So the priority order is render > template > el
Either template or el will be compiled into the render function, and if you already have the render function, skip the previous compilation
What about template compilation? How to render? More detailed content is a little more, specific can see my other article has the complete source code process details render function is how to come? Simple template compilation in Vue
Once you get the Render function, you’re ready for the mount phase
Mount the stage
So let’s look at the picture and see what we’re doing at this stage
As you can see from the diagram, there are two main things to do here
- Create a real DOM node based on the virtual DOM returned by Render, insert it into the view, and finish rendering
- Reactive processing of data or state in a template
mountComponent()
Let’s look at the source code for the mount. Here I have deleted a little bit about the environment judgment to see the main flow
The main thing we’re doing here is
- Calling hook functions
beforeMount
- call
_update()
Method to the old and new virtual DOMpatch
As well asnew Watcher
Reactive processing of template data - Call the hook function
mounted
Source address: SRC/core/instance/lifecycle. The js – 141 line
export function mountComponent (vm: Component, el: ? Element, hydrating? : boolean) :Component {
vm.$el = el
// Check whether there is a render function
if(! vm.$options.render) {// If not, a comment node is created by default
vm.$options.render = createEmptyVNode
}
// Call the lifecycle hook function
callHook(vm, 'beforeMount')
let updateComponent
updateComponent = () = > {
// Call _update to patch (Diff) the virtual DOM returned by render to the real DOM for the first time
vm._update(vm._render(), hydrating)
}
// Set an observer for the current component instance to monitor the data obtained by the updateComponent function, as described below
new Watcher(vm, updateComponent, noop, {
// When an update is triggered, it is called before the update
before () {
// Check whether the DOM is mounted, that is, it will not be executed during the first rendering and unloading
if(vm._isMounted && ! vm._isDestroyed) {// Call the lifecycle hook function
callHook(vm, 'beforeUpdate')}}},true /* isRenderWatcher */)
hydrating = false
// There is no old vNode, indicating the first rendering
if (vm.$vnode == null) {
vm._isMounted = true
// Call the lifecycle hook function
callHook(vm, 'mounted')}return vm
}
Copy the code
Watcher
About the response type principle, you can see my other article introduced in detail will not move over, simple Vue response type principle source code analysis
_update()
Then understand the entrance to patch, the complete process analysis of the source code of Diff algorithm, you can see my other article is very detailed, I will not move over, simple and simple virtual DOM and Diff algorithm, and Vue2 and Vue3 in the difference
Source address: SRC/core/instance/lifecycle. Js – 59
Vue.prototype._update = function (vnode: VNode, hydrating? : boolean) {
const vm: Component = this
const prevEl = vm.$el // Root node of the current component
const prevVnode = vm._vnode / / old vnode
vm._vnode = vnode // Update the old vNode
// Render for the first time
if(! prevVnode) {// Patch vnode to create a real DOM and mount it to vm.$el
vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)}else {
// During the modification, compare the old and new vNodes and return the modified real DOM
vm.$el = vm.__patch__(prevVnode, vnode)
}
// Delete the reference to the old root node
if (prevEl) prevEl.__vue__ = null
// Update the reference to the current root node
if (vm.$el) vm.$el.__vue__ = vm
// Update the parent reference
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
vm.$parent.$el = vm.$el
}
}
Copy the code
Destruction of phase
So let’s look at the picture and see what we’re doing at this stage
Vue is now in the destruction phase when the vm.$destroy() method is called.
$destroy()
This stage is relatively simple, source code is not much, mainly is:
- Call the lifecycle hook function
beforeDestory
- Removes the current component from the parent component
- Remove all observers within the current component (dependency tracing), remove references to data objects, and remove the virtual DOM
- Call the lifecycle hook function
destoryed
- Disable all event listening, remove references to the current root component, and remove references to the parent
I’ve put every line in the comments, so look at that
Source address: SRC/core/instance/lifecycle. The js – 97 line
Vue.prototype.$destroy = function () {
const vm: Component = this
// If the instance is in the process of being destroyed, skip it
if (vm._isBeingDestroyed) {
return
}
// Call the lifecycle hook function
callHook(vm, 'beforeDestroy')
// Update the destruction process status
vm._isBeingDestroyed = true
// Get the parent
const parent = vm.$parent
// If the parent exists and is not being destroyed, and is not an abstract component but a real one (
is an abstract component, its abstract is true)
if(parent && ! parent._isBeingDestroyed && ! vm.$options.abstract) {// Remove the current component from the parent
remove(parent.$children, vm)
}
// Remove all observers of the instance
if (vm._watcher) {
// Remove instance dependencies
vm._watcher.teardown()
}
let i = vm._watchers.length
while (i--) {
// Remove the dependency of data within the instance on other data
vm._watchers[i].teardown()
}
// Delete the reference to the data object
if (vm._data.__ob__) {
vm._data.__ob__.vmCount--
}
// Update the component destruction status
vm._isDestroyed = true
// Delete the virtual DOM of the instance
vm.__patch__(vm._vnode, null)
// Call the lifecycle hook function
callHook(vm, 'destroyed')
// Turn off all event listening
vm.$off()
// Remove the reference to the current root component
if (vm.$el) {
vm.$el.__vue__ = null
}
// Delete the parent reference
if (vm.$vnode) {
vm.$vnode.parent = null}}Copy the code
When $destroy() is called
SRC /core/vdom/patch.js; SRC /core/vdom/patch.js
- The new vnode does not exist. If the old vnode exists, the destroy function of the corresponding vnode is triggered. Line 702
- If the new vNode root node is modified, call destroy of the component corresponding to the old vnode. Line 767
- After the comparison between the old and new VNodes is complete, invoke destroy of the component corresponding to the old vNode. Line 795
At this point, the full Vue life cycle is complete
Past wonderful
- Simple Vue response type source code analysis
- Where does the render function come from? Simple template compilation in Vue
- Simple virtual DOM and Diff algorithms, and Vue2 and Vue3 differences
- Vue3 7 and Vue2 12 components communication, worth collecting
- What are the latest updates to Vue3.2
- JavaScript advanced knowledge
- Front-end anomaly monitoring and DISASTER recovery
- 20 minutes to help you learn HTTP and HTTPS, and consolidate your HTTP knowledge
conclusion
If this article is of any help to you, please give it a thumbs up. Thank you