This is the sixth day of my participation in Gwen Challenge.

preface

Earlier, we introduced the virtual DOM. In this article, we’ll learn what a VNode is, what a VNode does, and what the differences are between different types of VNodes.

What is a VNode

Virtual nodes as the name suggests. We can use it to instantiate different types of VNode instances. Different vNode instances represent different types of DOM elements.

DOM elements have element nodes, text nodes, and comment nodes, and accordingly, vNode instances.

What does a VNode class look like

export default class VNode {
    constructor(tag, data, children, text, elm, contexxtt, componentOptions, asyncFactory) {
        this.tag = tag;
        this.data = data;
        this.children = children;
        this.text = text;
        this.elm = elm;
        this.ns = undefined;
        tthis.context = context;
        this.functionalContext = undefined;
        this.functionalOptions = undefined;
        this.functionalScoped = undefined;
        this.key = data && data.key;
        this.componentOptions = componentOptions;
        this.componentInstance = undefined;
        this.parent = undefined;
        this.raw = false;
        this.isStatic = false;
        this.isRootInsert = true;
        this.isComment = false;
        this.isCloned = false;
        this.isOnce = false;
        this.asyncFactory = asyncFactory;
        this.asyncMeta = undefined;
        this.isAsyncPlaceholder = false;
    }
    
    get child() {return this.componentInstance
    }
}

Copy the code

Simply put, a VNode can be understood as a node description object, which describes how to create real DOM nodes.

Vnode represents a real DOM element, and all real DOM nodes are created using vNode and inserted into the page:

Graph LR v[vnode] --create--> d[DOM] --insert--> view

The above flowchart shows the process of creating a real DOM using VNode and rendering it into a view.

The role of the VNode

Since a VNode is created during each rendering of a view and then used to create a real DOM to insert into the page, you can cache the amount of vNodes created during the last rendering of the view, and then compare the newly created vNode with the last cached VNode whenever you need to re-render the view. Look for any differences between them, find those differences and modify the real DOM based on them.

Vue.js currently has a medium granularity strategy for state detection, notifying only components that use that state when a state changes.

Graph w[web page] === a[component] w === b[component] w === c[component]

The type of the VNode

There are many types of vNodes.

Comment node

Creating a comment node

export const createEmptyNode = text= > {
    const node = new VNode();
    node.text = text;
    node.isComment = true;
    return node;
}
Copy the code

The comment node has only two valid attributes, text and isComment.

A real comment node:

<! -- Comment node -->
Copy the code

The corresponding VNodes are as follows:

{
    text: 'Comment node'.isComment: true
}
Copy the code

Text node

The text is simple

export function createTextVNode(val){
    return new VNode(undefined.undefined.undefined.String(val))
}
Copy the code

A text node has only one valid attribute — text

Clone node

Cloning node is to copy the properties of the existing node to the new node, so that the properties of the newly created node and the cloned node are consistent, so as to achieve the cloning effect. It is used to optimize static nodes and slot nodes.

Take the static node as an example. When a certain state in the component changes, the current component will re-render the view through the virtual DOM. Since the content of the static node does not change, it does not need to perform the rendering function to regenerate the VNode except for the first rendering. Therefore, a clone of the vNode will be created using the same method as the clone node, and the clone node will be used for rendering.

export function cloneVNode(vnode, deep) {
    const cloned = new VNode(
        vnode.tag,
        vnode.data,
        vnode.children,
        vnode.text,
        vnode.elm,
        vnode.context,
        vnode.componentOptions,
        vnode.asyncFactory
    )
    cloned.ns = vnode.ns;
    cloned.isStatic = vnode.isStatic;
    cloned.key = vnode.key;
    vloned.isComment = vnode.isComment;
    cloned.isCloned = true;
    if (deep && vnode.children ) {
        cloned.children = cloneVNodes(vnode.children)
    }
    return cloned;
Copy the code

The only difference between clone nodes and cloned nodes is the isempirical attribute.

Element nodes

Element nodes typically have the following four valid attributes:

  • tag
  • Data (attrs, class, style, etc.)
  • children
  • context

An actual element node:

<p><span>hello world</span></p>
Copy the code

Corresponding VNode:

{
    children: [VNode],
    contextt: {... },data: {... },tag: 'p'. }Copy the code

Component node

Like element nodes, component nodes have two unique attributes:

  • componentOptions
  • componentInstance

A component node:

<child></child>
Copy the code

Corresponding VNode:

{
    componentInstance: {... },componentOptions: {... },context: {... },data: {... },tag: 'child'. }Copy the code

Functional component

Functional components may not be used much, you can go to the official website to review. (Functional components)

A functional component is like a component node in that it has two unique properties

  • functionalContext
  • functionalOptions
{
    functionalContext: {... },functionalOptions: {... },context: {... },data: {... },tag: 'div'. }Copy the code

conclusion

In short, a VNode is a class that can generate different types of instances, and different types of VNodes represent different types of real DOM elements.