Principle of Component Rendering Mechanism in Virtual DOM
Principle of Component Rendering Mechanism in Virtual DOM
The component rendering mechanism of the Virtual DOM refers to the process of describing the component tree through virtual nodes (VNodes) and converting components into real DOM. Its core lies in the creation of component-type VNodes, component instantiation, lifecycle management, and recursive rendering of child components. The following is a step-by-step analysis:
1. Creation of Component VNode
- Description: The Virtual DOM distinguishes between ordinary element nodes (e.g.,
div) and component nodes (e.g., Vue components). A component VNode contains information such as the component definition (e.g., options object or functional component), props, children, etc. - Process:
- The compiler parses component tags in the template (e.g.,
<MyComponent>) intocreateVNodecalls and marks theshapeFlagasCOMPONENT(e.g.,ShapeFlags.STATEFUL_COMPONENTin Vue 3). - Example code:
// Creation of Component VNode const componentVNode = createVNode(MyComponent, { title: 'Example' }, children);
- The compiler parses component tags in the template (e.g.,
2. Component Instantiation and Initialization
- Description: When rendering a component, it is necessary to instantiate the component object, handling props, state, lifecycle, etc.
- Process:
- Instantiation: Create an instance based on the type of the component VNode (stateful component/functional component). For example, in Vue 3,
createComponentInstanceis called to generate an instance containing props, setup state, lifecycle queues, etc. - Establishing Instance Relationships: Establish a bidirectional association between the instance and the VNode (
vnode.component = instance). - Initializing props and slots: Parse the props and children from the VNode and inject them into the instance.
- Executing Lifecycle Hooks: Such as
beforeCreate,created(Vue 2) orsetup(Vue 3).
- Instantiation: Create an instance based on the type of the component VNode (stateful component/functional component). For example, in Vue 3,
3. Execution of Component Render Function and Generation of Child VNodes
- Description: Call the component's render function (or the render function compiled from the template) to generate the subtree of child VNodes for that component.
- Process:
- Execute the render function (e.g.,
setupRenderEffectin Vue 3), passing in props and slots, returning a VNode tree describing the component's internal structure. - Example:
// Component internal render function const subtree = instance.render.call(instance.proxy); - The generated
subtreeat this point is composed of ordinary element VNodes or other component VNodes, forming a nested structure.
- Execute the render function (e.g.,
4. Recursive Processing of Child VNodes
- Description: Recursively
patchthesubtreegenerated by the component to convert it into real DOM. - Process:
- Call the
patchfunction to process thesubtree, following different logic based on the child VNode type:- If it is an element VNode, create the DOM element and set attributes.
- If it is a component VNode, return to Step 2 to recursively instantiate the child component.
- Eventually, all components and elements are processed into real DOM, forming a complete DOM tree.
- Call the
5. Lifecycle and Update Mechanism
- Description: When a component mounts/updates, lifecycle hooks (e.g.,
mounted,updated) are triggered, and reactive updates are achieved through dependency tracking. - Process:
- After Mounting: After recursing to leaf elements, trigger the
mountedhook in reverse order. - Update Mechanism: If the reactive data the component depends on changes, trigger the component to re-render (generating a new subtree), and use a diff algorithm to compare the old and new VNodes, updating the DOM locally.
- After Mounting: After recursing to leaf elements, trigger the
6. Special Handling of Functional Components
- Description: Functional components have no instance; the function is directly executed to return a VNode.
- Process:
- Call the functional component (e.g.,
const subtree = FunctionalComponent(props)). - Directly
patchthe returnedsubtree, skipping the instantiation process for higher performance.
- Call the functional component (e.g.,
Summary
The Virtual DOM's component rendering mechanism enables declarative component-based development through describing the component tree with VNodes, managing state via instantiation, and recursively patching to generate DOM. Its advantages include:
- Cross-platform: VNodes can be rendered into UI for different platforms (e.g., Web, mini-programs).
- Efficient Updates: Minimizes DOM operations with the help of diff algorithms.
- Logic Reusability: The component instantiation pattern encapsulates logic such as lifecycle and state management.