In order to facilitate their consolidation and understanding of knowledge points, sorted out the Big guy Li Yongning 12 “Vue source code interpretation” at the end of the summary of knowledge points, here you can see the world. If you want to read more, click “Read the original” under the title.

(1) Preface

Read the original

(2) Vue initialization process

Read the original

What does the initialization process for Vue(new Vue(options)) do?

  • Handle component configuration items
    • When the root component is initialized, an option merge operation is performed to merge the global configuration onto the local configuration of the root component
    • Some performance optimizations were made when each subcomponent was initialized, and some deep properties on the component configuration object were placed in the VM.$options option to improve code execution
  • Initialize the relationship properties of the component instance, such as parent, parent, parent, children, root, root, root, refs, and so on
  • Handle custom events
  • Call the beforeCreate hook function
  • Initialize the inject configuration item of the component, obtain the configuration object in the form of Ret [key] = val, and then perform reactive processing on the configuration object, and proxy each key to the VM instance
  • Data response, such as props, methods, data, computed, and watch
  • Resolve the provide object on the component configuration item and mount it to the VM. _provided property
  • Call the created hook function
  • If the EL option is found on the configuration item, it is automatically invoked$mountMethod, that is, with the EL option, there is no need to call it manually$mountMethod, otherwise, the EL option must be called if it is not provided$mount
  • Next, you enter the mount phase

(3) Response principle

Read the original

How is the Vue response principle implemented?

  • The core of responsiveness is intercepting access to and setting up data via object.defineProperty
  • Response-based data are divided into two categories:
    • Object, iterating through all properties of the object, setting getters and setters for each property to intercept access and setting. If the property value is still an object, then recursively setting getters and setters for each key on the property value
      • Dependencies are collected when data is accessed (obj.key), and associated watcher is stored in deP
      • When setting the data, deP informs the relevant watcher to update it
    • Array, the seven prototype methods that enhance the array can change themselves, and then intercept operations on those methods
      • When new data is added, it is processed responsively, and the DEP informs watcher to update it
      • When deleting data, deP also notifishes watcher to update it

What is the difference between Methods, computed and Watch?

<! DOCTYPEhtml>
<html lang="en">

<head>
  <title>What is the difference between Methods, computed, and Watch</title>
</head>

<body>
  <div id="app">
    <! -- methods -->
    <div>{{ returnMsg() }}</div>
    <div>{{ returnMsg() }}</div>
    <! -- computed -->
    <div>{{ getMsg }}</div>
    <div>{{ getMsg }}</div>
  </div>
  <script src=".. /.. /dist/vue.js"></script>
  <script>
    new Vue({
    el: '#app'.data: {
      msg: 'test'
    },
    mounted() {
      setTimeout(() = > {
        this.msg = 'msg is changed'
      }, 1000)},methods: {
      returnMsg() {
        console.log('methods: returnMsg')
        return this.msg
      }
    },
    computed: {
      getMsg() {
        console.log('computed: getMsg')
        return this.msg + ' hello computed'}},watch: {
      msg: function(val, oldVal) {
        console.log('watch: msg')
        new Promise(resolve= > {
          setTimeout(() = > {
            this.msg = 'msg is changed by watch'
          }, 1000)})}})</script>
</body>

</html>
Copy the code

The example is actually the answer

  • Usage scenarios
    • Methods are used to encapsulate more complex processing logic (synchronous, asynchronous)
    • Computed is typically used to encapsulate some simple synchronization logic that returns processed data and then displays it in the template to reduce the weight of the template
    • Watch is typically used to perform asynchronous or expensive operations when data changes
  • The difference between
    • methods VS computed
      • As you can see from the example, if the same Methods or computed property is used in multiple places during a rendering, the methods will be executed multiple times, while the computed callback will be executed only once.
      • For example, if you access a computedProperty multiple times during a render, only the first computedProperty callback is executed for the computed property, and the rest of the computedProperty callback is executed for the first time (watcher.value). This is done by controlling the watcher.dirty property. Methods, on the other hand, each access is a simple method call (this.xxMethods).
    • computed VS watch
      • By reading the source code, we know that computed and Watch are the same in nature, and both are implemented internally by Watcher. In fact, there is no difference between them. There are two differences: 1.
    • methods VS watch
      • In fact, there is no comparison between methods and watch, they are completely two things. However, in terms of use, some logic of Watch can be extracted into methods to improve the readability of code.

(4) Asynchronous update

Read the original

How is Vue’s asynchronous update mechanism implemented?

  • The core of Vue’s asynchronous update mechanism is realized by using the asynchronous task queue of the browser, with the microtask queue being the first choice and the macro task queue being the second.
  • When the reactive data is updated, the dep. Notify method is called and the watcher collected in the DEP is notified to perform the update method. Watcher.update puts the watcher on a watcher queue (global queue array).
  • We then place a method to flushSchedulerQueue into a global array of Callbacks via the nextTick method.
  • If the browser does not have a flushCallbacks function in the asynchronous task queue at this time, then timerFunc is executed to place the flushCallbacks function in the asynchronous task queue. If the asynchronous task queue already contains flushCallbacks, wait for the task to complete before putting the next flushCallbacks into the queue.
  • The flushCallbacks function is responsible for executing all flushSchedulerQueue functions in the Callbacks array.
  • FlushSchedulerQueue function is responsible for the refresh watcher queue, that executes each queue array watcher run method, to update the stage, such as the execution component update function or perform user watch the callback function.
  • The complete implementation process is actually the process of reading the source code today.

How is Vue’s nextTick API implemented?

NextTick or VM.$nextTick is simple. It does two things:

  • Wrap the passed callback in a try catch and place it in an array of Callbacks
  • Execute the timerFunc function to put a function that refreshes the array of Callbacks in the browser’s asynchronous task queue

(5) Global API

Read the original

What does vue.use (plugin) do?

To install a plugin, perform the install method provided by the plugin.

  • First determine if the plug-in has already been installed
  • If no, install the plug-in using the install method provided by the plug-in. The plug-in decides what to do

What does vue.mixin (Options) do?

Is responsible for merging options configurations on Vue’s global configuration. The global configuration is then merged into the component’s own configuration when each component generates a VNode.

  • Standardizes the formatting of props, inject, and directive options on the options object
  • Handle extends and mixins on Options, incorporating them into the global configuration, respectively
  • Then merge the options configuration with the global configuration. If the options conflict, the options configuration overrides the global configuration

What does Vue.com Ponent (compName, Comp) do?

Responsible for registering global components. The component configuration is registered with the global components option (options.com components), and then the sub-components will merge the global Components option into the local Components configuration when the vNode is generated.

  • If the second argument is empty, it indicates the component constructor that gets compName
  • If Comp is a component configuration object, use the vue. extend method to get the component constructor, otherwise go straight to the next step
  • Information on the global configuration Settings components, this.options.components.com pName = CompConstructor

What does vue. directive(‘my-directive’, {xx}) do?

Register the mY-Directive globally, and then each of the child directives merges the global directives into the local directives when the VNode is generated. The principle is the same as Vue.com Ponent method:

  • If the second argument is empty, the configuration object for the specified directive is obtained
  • {bind: second argument, update: second argument}}
  • Then set the directive configuration object to the global configuration, this.options. Directives [‘my-directive’] = {xx}

Vue.filter(‘my-filter’, function(val) {xx}) does what?

It is responsible for registering the mY-filter globally, and each subcomponent then merges the global filters option into the local filters option when generating the VNode. The principle is:

  • If the second argument is not provided, the callback function for the My-filter filter is obtained
  • Filters [‘my-filter’] = function(val) {xx} if the second argument is provided, set this.options. Filters [‘my-filter’] = function(val) {xx}.

What does vue.extend (Options) do?

Extend creates a subclass based on Vue, and the options parameter is the default global configuration for that subclass, just like the default global configuration for Vue. So extending a subclass with vue. extend is useful because it has built-in common configurations that can be used by subclasses of the subclass.

  • Define the subclass constructor, which, like Vue, calls _init(options).
  • Merge the Vue configuration and options. If the options conflict, the options overwrite the Vue configuration
  • Define a global API for a subclass with the value Vue global API, such as sub.extend = super.extend, so that the subclass can also extend to other subclasses
  • Return subclass Sub

What does vue.set (target, key, val) do?

Due to the Vue cannot detect common new property (such as this. MyObject. NewProperty = ‘hi’), so by the Vue. Set to add a response to objects of type property, You can ensure that the new property is also responsive and triggers view updates.

  • Set (array, idx, val). Internally, the splice method is used to implement responsive updates
  • Set (obj, key,val) => obj[key] = val
  • You cannot dynamically add root-level responsive data to a Vue instance or $data
  • Vue.set(obj, key, val). If obj is not a reactive object, obj[key] = val will be executed, but no reactive processing will be done
  • Vue.set(obj, key, val), add a new key to the responsive object obj, set the responsive using defineReactive method and trigger the dependency update

Interviewer: What did Vue.delete(target, key) do?

Delete the property of the object. If the object is reactive, make sure the deletion triggers an update to the view. This method is mainly used to get around the limitation that Vue cannot detect when a property is removed, but you should rarely use it. Of course, the same cannot be said for root level responsive attributes.

  • Vue.delete(array, idx), delete the element with the specified subscript, internally by splice
  • Delete an attribute on a responsive object: vue.delete (obj, key), internally delete obj.key, and then perform a dependency update

What does Vue.Nexttick (CB) do?

NextTick (cb) ¶ The nextTick(cb) method is used to delay the execution of the cb callback function. This is used to retrieve DOM data immediately after this. Key = newVal is changed:

this.key = 'new val'

Vue.nextTick(function() {
  // The DOM is updated
})
Copy the code

Its internal implementation process is:

  • This.key = ‘new val, triggering the dependency notification update, placing the watcher responsible for the update in the watcher queue
  • Put the function that refreshes the Watcher queue into the Callbacks array
  • Put a function to refresh the array of Callbacks in the browser’s asynchronous task queue
  • NextTick (cb) to jump the queue and put the CB function into the callbacks array
  • A function to refresh the array of Callbacks is executed at some point in the future
  • It then executes a number of functions in the Callbacks array, triggering the execution of watcher.run and updating the DOM
  • Since the CB function is placed later in the Callbacks array, this ensures that the DOM update is completed before the CB function is executed

(6) Instance methods

Read the original

What does vm.$set(obj, key, val) do?

Vm.$set is used to add a new property to the responsive object, ensure that the new property is also responsive, and trigger the view update. NewProperty = ‘val’, this.arr[3] = ‘val’. Hence the vm.$set, which is an alias for vue.set.

  • Add a new reactive data to the object: Call defineReactive method to add reactive data to the object, then perform dep.notify for dependency notification and update the view
  • Add a new reactive data to the array: through splice

$delete(obj, key) does what?

Vm.$delete is used to delete attributes on an object. If the object is reactive and you can ensure that the view updates are triggered. This method is mainly used to avoid the case where Vue cannot detect that an attribute is deleted. It is an alias for vue.delete.

  • Delete the element of the specified index in the array. This is done internally by splice
  • To delete a specified property on an object, first delete the property using the delete operator, and then execute dep.notify to update the view

$watch(expOrFn, callback, [options]) what did VM.$watch(expOrFn, callback, [options]) do?

Vm.$watch watches for changes in the result of an expression or function on the Vue instance. When this changes, the callback function is executed and two arguments are passed to the callback, the first being the updated new value and the second the old value.

One thing to note here is that if you’re looking at an object, for example: Array. When you add an element to the array using an array method such as push, the new value passed by the callback is the same as the old one because they refer to the same reference, so be careful when looking at an object and seeing whether the old and new values are equal in the callback.

The first argument of vm.$watch only accepts the key path of simple responsive data. For more complex expressions, it is recommended to use a function as the first argument.

The inner workings of VM.$watch are:

  • Set options.user = true, indicating a user watcher
  • Instantiate a Watcher instance. When an update is detected, the Watcher triggers the callback function to execute, passing the old and new values as arguments to the callback function
  • Returns an unwatch function to cancel the observation

What does vm.$on(event, callback) do?

Listen for custom events on the current instance that can be fired by vm.$emit, and the callback function receives all additional arguments passed in to the event firing function vm.$emit.

Vm $on principle is very simple, is dealing with transfer of the event and the callback two parameters, the registration of events and back DiaoHan tens of key-value pairs stored to the vm. The _event object, vm. _events = {eventName: [cb1, cb2, …] . }.

$emit(eventName, […args])

Fires the specified event on the current instance, with any additional arguments passed to the event’s callback function.

Internally, it executes all the callbacks in vm._events[eventName].

Remark: On and on and on and emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit emit On, VM. on, Vm. on, vm.on, and vm.emit are used internally to handle custom events.

What does vm.$off([event, callback]) do?

Removing a custom event listener removes data from the VM._events object.

  • If no argument is provided, all event listening for the instance is removed
  • If only the event argument is provided, all listeners for that event on the instance are removed
  • If both arguments are provided, the listener for the event is removed from the instance

What does vm.$once(event, callback) do?

Listen for a custom event, but the event is only fired once. Once triggered, the listener is removed.

Its internal implementation principle is:

  • $off(event, wrapper) removes the event in addition to the user callback
  • Use vm.$on(event, wrapper function) to register the event

What does vm._update(vnode, hydrating) do?

This API is not described in the official documentation. It is an instance method used inside the source code, which is responsible for updating the page. It is the entry point for the page rendering. This approach is not used in business development.

What does vm.$forceUpdate() do?

Forcing a Vue instance to re-render, it only affects the component instance itself and the child components inserted into the slot contents, not all child components. The internal principle is as simple as calling vm._watcher.update() directly, which is the watcher.update() method, which triggers component updates.

What does vm.$destroy() do?

Responsible for completely destroying an instance. Clean up its connections to other instances and unbind all its directives and event listeners. The beforeDestroy and Destroy hook functions are called during execution. This method is not used in most business development scenarios, and is generally operated by the V-if directive. Its internal principle is:

  • Call the beforeDestroy hook function
  • Destroy your relationship with your dad by removing yourself from his belly ($parent)
  • Remove the dependent listener with watcher.tearDown ()
  • The vm._ _ patch _ _(vnode, null) method is used to destroy the node
  • Call the destroyed hook function
  • Remove all event listeners using the vm.$off method

What does vm.$nextTick(cb) do?

NextTick is an alias for Vue. NextTick, which is used to delay the execution of the cb callback function. This.

this.key = 'new val'

Vue.nextTick(function() {
  // The DOM is updated
})
Copy the code

Its internal implementation process is:

  • This.key = ‘new val’, which triggers the dependency notification update, placing the watcher responsible for the update in the watcher queue
  • Put the function that refreshes the Watcher queue into the Callbacks array
  • Put a function to refresh the array of Callbacks in the browser’s asynchronous task queue
  • Vm.$nextTick(cb) to jump the queue and put the CB function directly into the callbacks array
  • A function to refresh the array of Callbacks is executed at some point in the future
  • It then executes a number of functions in the Callbacks array, triggering the execution of watcher.run and updating the DOM
  • Since the CB function is placed later in the Callbacks array, this ensures that the DOM update is completed before the CB function is executed

What does vm._render do?

This method, which is not provided in the official documentation, is an instance method used within the source code and is responsible for generating the VNode. Its key code is a single line, executing the render function to generate vNode. But it adds a lot of exception handling code.

(7) Hook Event

Read the original

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.

How is the Hook Event implemented?

<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

(8) Compiler parsing

Read the original text (part 1)

Read the text (part 2)

Interviewer: What does Vue’s compiler do briefly?

Vue’s compiler does three things:

  • Parse the component’s HTML template into an AST object
  • Optimization, traversing the AST, making static tags for each node, marking whether it is static node or not, and then further marking the static root node, so that these static nodes can be skipped in the process of subsequent updates; The tag static root is used in the render function generation phase to generate the render function for the static root node
  • Generate the runtime render function from the AST. There is also an array called staticRenderFns, which holds all the static node render functions

How does the compiler parse an HTML string template into an AST object?

  • Iterating over the HTML template string, matching “<” with a regular expression
  • Skip some unnecessary tags, such as annotation tags, conditional annotation tags, and Doctype.
    • Note: The core of the entire parsing process is to process the start and end tags
  • Parse the start tag
    • Get an object containing the tagName, all attributes (attrs), and the index position of the tag in the HTML template string
    • [{name: attrName, value: attrVal, start: xx, end: xx},…] In the form of
    • The AST object is generated by the label name, attribute object and the parent element of the current element. In fact, it is an ordinary JS object, which records some information of the element in the form of key and value
    • The instructions on the start tag, such as V-pre, V-for, V-IF, and V-once, are then further processed and the results are placed on the AST object
    • The AST object is stored in the stack array
    • When the processing is complete, the HTML string is truncated, truncating the string that has been processed
  • Parsed closing label
    • If the end tag is matched, the last element from the stack array is taken, which is a pair with the currently matched end tag.
    • Process the attributes on the start tag again, which are different from the previous ones, such as key, ref, scopedSlot, style, and so on, and place the results on the element’s AST object
      • Note: it is said in the video that this is wrong, but after looking back, there is no problem, no need to change, it is true
    • We then associate the current element with the parent element, set the parent property to the current element’s AST object, and place ourselves in the children array of the parent element’s AST object
  • After finally traversing the entire HTML template string, the AST object is returned

(9) Compiler optimization

Read the original

What does Vue’s compiler do briefly?

Vue’s compiler does three things:

  • Parse the component’s HTML template into an AST object
  • Optimization, traversing the AST, making static tags for each node, marking whether it is static node or not, and then further marking the static root node, so that these static nodes can be skipped in the process of subsequent updates; The tag static root is used in the render function generation phase to generate the render function for the static root node
  • The staticRenderFns array contains all static node render functions

Describe the static tag process in more detail

  • Marking static nodes
    • Mark all element nodes recursively
    • If the node itself is static, but there are non-static child nodes, modify the node to be non-static
  • Mark the static root node, based on the static node, further mark the static root node
    • If the node itself is static && and has children && whose children are not all text nodes, it is marked as static root
    • If the node itself is not a static root, it recursively traverses all the children, marking the static root among them

What kind of node can be marked as static?

  • Text node
  • No v-bind, V-for, or V-if instructions exist on the node
  • The component

(10) Compiler rendering function

Read the original

What does Vue’s compiler do briefly?

Vue’s compiler does three things:

  • Parse the component’s HTML template into an AST object
  • Optimization, traversing the AST, making static tags for each node, marking whether it is static node or not, and then further marking the static root node, so that these static nodes can be skipped in the process of subsequent updates; The tag static root is used in the render function generation phase to generate the render function for the static root node
  • The staticRenderFns array contains all static node render functions

Describe the rendering function generation process in detail

There are two types of render generated by the compiler:

  • The first is a render function that generates a vNode with dynamic nodes
  • The second is static rendering functions placed in an array called staticRenderFns, which are responsible for generating vNodes with static nodes

The rendering function generation process is actually traversing the AST nodes, processing each node through a recursive way, and finally generating the result of the form: _c(Tag, attr, children, normalizationType). Tag is the tag name, attr is the attribute object, children is an array of children, each of which is of the form _c(Tag, attr, children, normalizationTYpe). Normalization means the normalized type of the node, which is a number 0, 1, 2, and is not important.

In the process of dealing with AST nodes, we need to focus on the common questions in the interview:

  • How are static nodes handled (in two steps)?
    • Put the generating static node vnode function in the staticRenderFns array
    • Returns a_m(idx)The function of staticRenderFns executes the function of idx in the array staticRenderFns, generating a vnode with static nodes
  • How to deal with v-ONCE, V-IF, V-for, components, etc?
    • The processing mode of pure V-Once nodes is the same as that of static nodes
    • The result of processing the V-if node is a ternary expression
    • The processing result of the V-for node is executable_lFunction, which is responsible for generating vNodes for v-for nodes
    • Components are processed just like normal elements_c(compName)Executable code that generates components of vNode

twitter

At this point, the Vue compiler’s interpretation of the source code ends. I believe you will inevitably have a feeling in the process of reading. That’s okay. The compiler is the most complicated part of the framework, the most difficult part to understand and the most code. Be sure to calm down to read a few more times, encounter can not understand the place, be sure to work hard, through example code and breakpoint debugging way to help yourself understand.

After you’ve read it a few times, you’ll probably get better, but you’ll still get a little dizzy in some places, and that’s fine, that’s normal. After all, this is a framework compiler that handles a lot of stuff, and you just need to understand the core ideas (template parsing, static markup, code generation). A hand-written Vue series will follow, and a simplified implementation will be available in the compiler section to help deepen the understanding.

When the compiler reads through it, it will find that the code generated by the compiler is wrapped with, such as:

<div id="app">
  <div v-for="item in arr" :key="item">{{ item }}</div>
</div>
Copy the code

After compilation, generate:

with (this) {
  return _c(
    'div',
    {
      attrs:
      {
        "id": "app"
      }
    },
    _l(
      (arr),
      function (item) {
        return _c(
          'div',
          {
            key: item
          },
          [_v(_s(item))]
        )
      }
    ),
    0)}Copy the code

As we all know, the with statement extends the scope chain, so the _c, _L, _v, and _s in the generated code are methods on this, meaning that when executed at run time, these methods will generate vnodes for each node.

Therefore, in connection with the previous knowledge, the entire implementation process of responsive data update is:

  • Responsively intercepts updates to the data
  • The DEP informs Watcher to make an asynchronous update
  • The component update function updateComponent is executed when Watcher updates
  • The vnode of the vm._render generated component is executed first, which executes the compiler generated function

Question:

  • What are the _c, _l, _v, _s methods in the render function?
  • How do they generate vNodes?

The next article Vue source code Interpretation (11) — Render Helper will bring a detailed interpretation of this knowledge, which is often asked in interviews: for example: what is the principle of V-for?

(11) Render helper

Read the original

How does a component become a VNode?

  • The component instance is initialized, and then $mount is executed to enter the mount phase
  • If you include only the run-time vue.js, you only go straight to the mount phase, because the component is now a rendering function, and the compilation is done via the module packager + vue-loader + vue-template-compiler
  • If you are not using precompilation, you must use full vue.js
  • If the render option is not found on the component configuration item during the mount, the compile phase is entered
  • Compile the template string into an AST syntax tree, which is actually an ordinary JS object
  • Then optimize the AST, traverse the AST object, and mark whether each node is static static; The static root nodes are then further flagged, and updates to these static nodes are skipped on subsequent component updates to improve performance
  • Next, generate the render function from the AST. The generated render function consists of two parts:
    • Responsible for generating the dynamic node VNode render function
    • There is also an array of staticRenderFns, where each element is a function that generates a static VNode. These functions will be part of the render function that generates a VNode with a static node
  • Next, place the render function on the component’s configuration object and enter the mount phase by executing the mountComponent method
  • Ultimately responsible for rendering the component and updating the component is a method called updateComponent, which needs to be executed before each executionvm._renderFunction that executes the compiler generated render to get the VNode of the component
  • The actual work of generating a component to a VNode is done in the Render function_c,_o,_l,_mThese methods are mounted to the Vue instance and are responsible for generating the component VNode at run time

VNode is a JS object that represents a component template. It is a common JS object that describes the information of each node in the component

Set the component configuration information, and then use new VNode(component information) to generate the component VNode

  • _c, the VNode responsible for generating components or HTML elements,_cIs the most complex and core method of all the Render Helper methods_xxIt’s all part of it
    • Receive a label, a property JSON string, an array of child nodes, and a node normalization type as parameters
    • If the label is a platform-reserved label or an unknown element, then new VNode(label information) gets VNode
    • If the label is a component, the createComponent method is executed to generate the VNode
      • A functional component executes its own render function to generate a VNode
      • Ordinary components instantiate a VNode and set 4 methods on the data.hook object, which will be called in the patch phase of the component, thus entering the instantiation and mounting phases of the child components, and then compile and generate the rendering function until the rendering is completed
      • Of course, the VNode will be generated before some configuration processing such as:
        • Subcomponent options merge, merging global configuration items into component configuration items
        • V-model for handling custom components
        • PropsData (props); propsData (props); propsData (props); This happens again when a new VNode is generated when the component is updated, and this is how the props response works
        • Processing other data, such as listeners
        • Install built-in init, prepatch, INSERT, and destroy hooks to data.hooks objects that are used in the patch phase of the component
  • _lRender the helper function of the v-for list at runtime, iterating through the values of val, executing the render method to generate vNodes for each item in turn, and finally returning an array of VNodes
  • _m, the VNode responsible for generating static nodes, that is, executing the staticRenderFns array to set the index function

A simple summary of the function of the Render Helper is to mount some runtime utility methods on the Vue instance that are used in the compiler generated render function to generate the VNode of the component.

All that remains is the patch phase. The next article will show you how to render the VNode of a component to the page.

(12) patch

Read the original

Can you tell us about Vue’s patch algorithm?

Vue’s Patch algorithm has three functions: it is responsible for the first rendering and subsequent update or destruction of components

  • If the old VNode is a real element, render for the first time, create the whole DOM tree, insert the body, and then remove the old template node
  • If the old VNode is not a real element and the new VNode exists, the patchVnode is an update phase and the patchVnode is executed
    • The first is to fully update all properties
    • If both the old and new VNodes have children, then updateChildren is recursively executed, performing the diff process
      • The characteristics of front-end operation DOM nodes are optimized as follows:
      • Same level comparison (reduced time complexity) Depth first (recursion)
      • In addition, the node order is rarely completely messed up in the front end, so four assumptions are made. Assuming that there are the same nodes at the beginning and end of new and old Vnodes, once the assumption is matched, a loop is avoided, the time complexity of DIff is reduced, and the execution efficiency is improved. If the hypothesis is unfortunately not hit, a walk is performed to find the start node of the new VNode from the old VNode
      • If the same node is found, run patchVnode and move the old node to the correct location
      • If the traversal of the old VNode is completed before the new VNode, the remaining new Vnodes are added
      • If the new VNode finishes before the old VNode, the remaining old Vnodes perform a deletion operation to remove the old VNode
    • If the new VNode has children and the old VNode does not, these new child nodes are added
    • If the old VNode has children and the new VNode does not, delete the old child nodes
    • The other option is to update the text node
  • If the new VNode does not exist and the old VNode does exist, call Destroy to destroy the old VNode

twitter

Well, here, Vue source code interpretation series is over, if you seriously read the whole series of articles, I believe you are quite familiar with Vue source code, whether it is from the macro level of understanding, or some details of the detailed explanation, should be no problem. Even if some of the details aren’t clear right now, it’s easy to see where in the source code to look for answers when you run into problems.

Here you can try to retell Vue’s entire execution process in your own mind. The process is important, but the summation is the final moment of sublimation. If you get stuck in any link, you can go back and read the corresponding part.

Remember the goal from the first article in the series? Believe that reading several times down, you must be able to write in their resume: proficient in Vue framework source principles.

Next up is Vue’s handwriting series.

Author: Li Yongning

Link: juejin. Cn/user / 102879…

Source: Nuggets

The copyright belongs to the author. Commercial reprint please contact the author to obtain authorization, non-commercial reprint please indicate the source.