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.