Hello, I’m Karsong.

Recently noon no appetite, looking for VUE source code related video when meal drama. After a few meals, I got fat and VUE understood.

This article gives you a quick guide to the principles of VU3.

Module partition

If we use VUE’s template syntax definition:

<div>hello</div>
Copy the code

Eventually VUE will render the corresponding DOM nodes in the browser for us.

The description of this node changes four times, from compile to runtime:

Template syntax is converted by the compiler to the render function at compile time, like this:

render(h) {
  return h('div'.'hello');
}
Copy the code

At runtime, the result of the h function returned by the render function is a VNode (virtual DOM), like this:

{
  tag: "div".children: [{text: "Hello"}}]Copy the code

Finally, VUE renders the corresponding DOM in the browser based on VNode information.

So who is driving this process?

The mount and patch

Components have two different rendering logic: first rendering and update.

Rendering for the first time means creating something from scratch, as in VNode above:

{
  tag: "div".children: [{text: "Hello"}}]Copy the code

May correspond to the following DOM operations:

const node = document.createElement(VNode.tag);
node.textConent = 'Hello';
contanerDOM.appendChild(node);
Copy the code

Update requires a comparison between vNodes before and after the update, and DOM operations are performed on the changed parts.

For example, if the above VNode is changed to:

{
  tag: "div".children: [{/ / change the text
      text: "world"}}]Copy the code

Then the final execution:

node.textContent = 'world';
Copy the code

The first rendering of VUE corresponds to mount module, and the update corresponds to patch module.

So the render function returns VNode with mount or patch logic, depending on the situation:

If you want to in-depth knowledge of the virtual DOM, it is recommended to read snabbDOM source code. This is an excellent virtual DOM library, and the virtual DOM part of VUE2 is a fork of this library.

So who called the render function at what time?

Responsive update

In VUE, state changes are reflected in the view in real time, for example:

<div @click="count++">{{count}}</div>
Copy the code

After clicking div:

  1. Trigger click event, count changes

  2. The count change triggers a callback in which the view is updated

So far we know that the second step is due to triggering the following flow:

So just establish the connection between the count change and the render function.

Specifically, we want to implement Reactive and watchEffect:

// Define the state
const state = reactive({count: 0});

// Listen for state changes
watchEffect(() = > {
  console.log(state.count);
})

// Change the state
state.count++;
Copy the code

Reactive Defines the status.

WatchEffect determines which states to listen for based on how the callback executes.

For example, the watchEffect callback executes console.log(state.count); , he will listen for changes in state.

When performing state. Count++; Since watchEffect listens for state changes, its callback is triggered, printing state.count.

This is the Reactivity module.

VUE officially launched VUE3 responsive principle course to explain the implementation of Reactivity, this is the link to B station. If the economy allows, please support the legal version

When the Reactivity module is implemented, we can concatenate component state with subsequent processes.

As mentioned earlier, the render function is generated by the compiler based on template syntax. When faced with stateful template syntax, such as count above:

<div @click="count++">{{count}}</div>
Copy the code

The count in the render function is reactive({count: 0}).

You can then use watchEffect to listen for count changes.

So, when applying initialization, there is logic like this:

let isMounted = false;
let oldVNode;
watchEffect(() = > {
  if(! isMounted) {/ / the mount logic
    // Call the render function
    oldVNode = component.render();
    // mount
    mount(oldVNode);
  } else {
    / / patch logic
    // Call the render functionnewVNode = component.render(); patch(oldVNode, newVNode); oldVNode = newVNode; }})Copy the code

Component.render () (render function) does the same thing:

// Listen for state changes
watchEffect(() = > {
  console.log(state.count);
})
Copy the code

Therefore, any state change within this component triggers the execution of watchEffect, and subsequent processes are triggered within the watchEffect callback.

conclusion

VUE3 can be roughly divided into:

  • mount

  • patch

  • The compiler

  • Reactivity

VUE officially launched a simple VUE3 tutorial, interested friends can go to see. If you have the ability, remember to support the original oh.