In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "Vue 3.0 advanced how to use VNode", the article explains the content is simple and clear, easy to learn and understand, now please follow the editor's ideas slowly in depth, together to study and learn "Vue 3.0 advanced how to use VNode" bar!
What does VNode look like?
/ / packages/runtime-core/src/vnode.ts export interface VNode
< HostNode = RendererNode, HostElement = RendererElement, ExtraProps = { [key: string]: any } >{/ / omit internal attributes}
In the runtime-core/src/vnode.ts file, we found the type definition of VNode. According to the type definition of VNode, VNode is essentially an object, which can be divided into five categories according to the function of attributes. Here, Brother Po only describes in detail the two common types of attributes-internal attributes and DOM attributes:
1.1 Internal attributes
_ _ v_isVNode: true / / indicates whether it is VNode [ReactiveFlags.SKIP]: true / / indicates that VNode is not observable type: VNodeTypes / / VNode type props: (VNodeProps & ExtraProps) | null / / attribute information key: string | number | null / / Virtual DOM algorithm ref: VNodeNormalizedRef | null / / which is mainly used in Vue is used to register reference information for elements or subcomponents. ScopeId: string | null / / SFC only children: VNodeNormalizedChildren / / Save child node component: ComponentInternalInstance | null / / points to the component instance corresponding to VNode dirs: DirectiveBinding [] | null / / saves the instruction information applied in VNode transition: TransitionHooks | null / / stores transition effect information
1.2 DOM Properties
El: HostNode | null / / element anchor: HostNode | null / / fragment anchor target: HostElement | null / / teleport target targetAnchor: HostNode | null / / teleport target anchor staticCount: number / / number of elements contained in a static vnode
1.3 suspense attribut
Suspense: SuspenseBoundary | null ssContent: VNode | null ssFallback: VNode | null
1.4 optimization attribute
ShapeFlag: number patchFlag: number dynamicProps: string [] | null dynamicChildren: VNode [] | null
1.5 Application context Properties
AppContext: AppContext | null
2. How to create VNode?
To create a VNode object, we can use the h function provided by Vue. It might be more accurate to name it createVNode (), but it is called h () because of its frequent use and simplicity. This function takes three parameters:
/ / packages/runtime-core/src/h.ts export function h (type: any, propsOrChildren?: any, children?: any): VNode {const l = arguments.length if (l = 2) {if (isObject (propsOrChildren) & &! isArray (propsOrChildren)) {/ / single vnode without props if (isVNode (propsOrChildren)) {return createVNode (type, null) [propsOrChildren])} / / contains only attributes and no child elements return createVNode (type, propsOrChildren) / / h ('div', {id:' foo'})} else {/ / ignore attributes return createVNode (type, null, propsOrChildren) / / h ('div' Else {if (l > 3) {children = Array.prototype.slice.call (arguments, 2)} else if (l = 3 & & isVNode (children)) {children = [children]} return createVNode (type, propsOrChildren, children)}}
Looking at the above code, we can see that the main processing logic inside the h function is to perform the corresponding processing operations according to the number and type of parameters, but in the end, the VNode object is created by calling the createVNode function. Before introducing the createVNode function, Brother Po gives some examples in actual development:
Const app = createApp ({/ / example 1 render: () = > h ('div',' I am Brother Po') const Comp = () = > h ("p", "I am Brother Po"); / / example 2 app.component ('component-a', {/ / example 3 template: "
I'm Brother Po.
"})
Example 1 and example 2 obviously use the h function, while example 3 does not see the h or createVNode function. To find out, we need to compile it with the help of Vue 3 Template Explorer, an online tool.
I'm Brother Po.
"template, the compiled result is as follows (function mode):
/ / https://vue-next-template-explorer.netlify.app/ const _ Vue = Vue return function render (_ ctx, _ cache, $props, $setup, $data, $options) {with (_ ctx) {const {createVNode: _ createVNode, openBlock: _ openBlock, createBlock: _ createBlock} = _ Vue return (_ openBlock (), _ createBlock ("p", null, "I am Brother Po"))}}
As can be seen from the above compilation results, "
I'm Brother Po.
"the template is compiled to generate a render function, which returns the result of the call to the createBlock function. The implementation of the createBlock function is as follows:
/ / packages/runtime-core/src/vnode.ts export function createBlock (type: VNodeTypes | ClassComponent, props?: Record | null, children?: any, patchFlag?: number, dynamicProps?: string []): VNode {const vnode = createVNode (type, props, children, patchFlag, dynamicProps, true / * isBlock: prevent a block from tracking itself * /) / omit part of the code return vnode}
Inside the createBlock function, we finally see the createVNode function. As the name implies, the function is used to create a VNode, so let's analyze it.
Third, what is done inside the createVNode function?
Next, we will introduce the createVNode function from two aspects: parameter description and logic description:
3.1 Parameter description
/ / packages/runtime-core/src/vnode.ts export const createVNode = (_ _ DEV__? CreateVNodeWithArgsTransform: _ createVNode) as typeof _ createVNode function _ createVNode (type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT, props: (Data & VNodeProps) | null = null, children: unknown = null, patchFlag: number = 0, dynamicProps: string [] | null = null, isBlockNode = false): VNode {/ / return vnode}
Before we analyze the specific code of the function, let's take a look at its parameters. This function can accept six parameters. Here, Brother Po uses mind mapping to focus on the first two parameters:
Type parameter
/ / packages/runtime-core/src/vnode.ts function _ createVNode (type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT, / / other parameters are omitted): VNode {...}
As you can see from the figure above, the type parameter supports many types, such as the commonly used string, VNode, and Component. In addition, there are some unfamiliar faces, such as Text, Comment, Static and Fragment, which are defined as follows:
/ / packages/runtime-core/src/vnode.ts export const Text = Symbol (_ _ DEV__? 'Text': undefined) export const Comment = Symbol (_ _ DEV__? 'Comment': undefined) export const Static = Symbol (_ _ DEV__? 'Static': undefined) export const Fragment = (Symbol (_ _ DEV__? 'Fragment': undefined) as any) as {_ _ isFragment: true new (): {$props: VNodeProps}}
So what's the point of defining so many types? This is because during the patch phase, different operations are performed according to different VNode types:
/ / packages/runtime-core/src/renderer.ts function baseCreateRenderer (options: RendererOptions, createHydrationFns?: typeof createHydrationFunctions): any {const patch: PatchFn = (N1, N2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) = > {/ / omit some codes const {type, ref, shapeFlag} = N2 switch (type) {case Text: / / processing text nodes processText (N1, N2, container) Anchor) break case Comment: / / process comment node processCommentNode (N1, N2, container, anchor) break case Static: / / process static node if (N1 = = null) {mountStaticNode (N2, container, anchor, isSVG)} else if (_ _ DEV__) {patchStaticNode (N1, N2, container) IsSVG)} break case Fragment: / / process Fragment node processFragment (...) Break default: if (shapeFlag & ShapeFlags.ELEMENT) {/ / element type processElement (...)} else if (shapeFlag & ShapeFlags.COMPONENT) {/ / component type processComponent (...)} else if (shapeFlag & ShapeFlags.TELEPORT) {/ / teleport built-in component (type as typeof TeleportImpl) .process (...)} else if (_ _ FEATURE_SUSPENSE__ & & shapeFlag & ShapeFlags.SUSPENSE) {; (type as typeof SuspenseImpl) .process (...)}
After introducing the type parameters, let's take a look at the props parameters, as shown below:
Props parameter
Function _ createVNode (type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT, props: (Data & VNodeProps) | null = null,): VNode {.}
The type of the props parameter is the union type. Here we analyze the Data & VNodeProps crossover type:
Where the Data type is defined through TypeScript's built-in tool type Record:
Export type Data = Record type Record = {[P in K]: t;}
VNodeProps types are defined by type aliases. Except for the key and ref attributes, other properties mainly define hooks related to the life cycle:
/ / packages/runtime-core/src/vnode.ts export type VNodeProps = {key?: string | number ref?: VNodeRef / / vnode hooks onVnodeBeforeMount?: VNodeMountHook | VNodeMountHook [] onVnodeMounted?: VNodeMountHook | VNodeMountHook [] onVnodeBeforeUpdate?: VNodeUpdateHook | VNodeUpdateHook [] onVnodeUpdated?: VNodeUpdateHook | VNodeUpdateHook [] onVnodeBeforeUnmount?: VNodeMountHook | VNodeMountHook [] onVnodeUnmounted?: VNodeMountHook | VNodeMountHook []}
3.2 logical explanation
The createVNode function involves a lot of processing logic, so here we analyze only the main logic:
/ / packages/runtime-core/src/vnode.ts function _ createVNode (type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT, props: (Data & VNodeProps) | null = null, children: unknown = null, patchFlag: number = 0, dynamicProps: string [] | null = null, isBlockNode = false): VNode {/ / handle VNode type For example, a scenario dealing with dynamic components: if (isVNode (type)) {const cloned = cloneVNode (type, props, true / * mergeRef: true * /) if (children) {normalizeChildren (cloned) Children)} return cloned} / / Class component normalization process if (isClassComponent (type)) {type = type.__vccOpts} / / Class and style normalization process if (props) {/ / omit the relevant code} / / convert the type information of vnode to bitmap const shapeFlag = isString (type)? ShapeFlags.ELEMENT / / ELEMENT = 1: _ _ FEATURE_SUSPENSE__ & & isSuspense (type)? ShapeFlags.SUSPENSE / / SUSPENSE = 1 cloned VNode return child.el = null? Child: cloneVNode (child)} else {/ / primitive types:'foo' or 1 return createVNode (Text, null, String (child))}}
As you can see from the above code, the normalizeVNode function is handled differently according to the type of child parameter:
4.1 null / undefined-> Comment
Expect (normalizeVNode (null)) .toMatchObject ({type: Comment}) expect (normalizeVNode (undefined)) .toMatchObject ({type: Comment})
4.2 boolean-> Comment
Expect (normalizeVNode (true)) .toMatchObject ({type: Comment}) expect (normalizeVNode (false)) .toMatchObject ({type: Comment})
4.3 array-> Fragment
Expect (normalizeVNode (['foo'])) .toMatchObject ({type: Fragment})
4.4 VNode-> VNode
Const vnode = createVNode ('div') expect (normalizeVNode (vnode)) .tobe (vnode)
4.5 mounted VNode-> cloned VNode
Const mounted = createVNode ('div') mounted.el = {} const normalized = normalizeVNode (mounted) expect (normalized) .not.tobe (mounted) expect (normalized) .toEqual (mounted)
4.6 primitive types
Expect (normalizeVNode ('foo')) .toMatchObject ({type: Text, children: `foo`}) expect (normalizeVNode (1)) .toMatchObject ({type: Text, children: `1`})
Brother Po has something to say
5.1 how to determine whether it is a VNode object or not?
/ / packages/runtime-core/src/vnode.ts export function isVNode (value: any): value isVNode {return value? Value.__v_isVNode = true: false}
There is a _ _ v_isVNode internal attribute in the VNode object, which can be used to determine whether the current object is a VNode object.
5.2 how can I determine whether two VNode objects are of the same type?
/ / packages/runtime-core/src/vnode.ts export function isSameVNodeType (N1: VNode, N2: VNode): boolean {/ / omit the processing logic of _ _ DEV__ environment return n1.type = n2.type & & n1.key = n2.key}
In Vue 3, you compare the type and key properties of VNode objects to determine whether the two VNode objects are of the same type.
5.3 how can I quickly create certain types of VNode objects?
CreateTextVNode, createCommentVNode, and createStaticVNode functions are provided within Vue 3 to quickly create text nodes, comment nodes, and static nodes:
CreateTextVNode
Export function createTextVNode (text: string ='', flag: number = 0): VNode {return createVNode (Text, null, text, flag)}
CreateCommentVNode
Export function createCommentVNode (text: string ='', asBlock: boolean = false): VNode {return asBlock? (openBlock (), createBlock (Comment, null, text)): createVNode (Comment, null, text)}
CreateStaticVNode
Export function createStaticVNode (content: string, numberOfNodes: number): VNode {const vnode = createVNode (Static, null, content) vnode.staticCount = numberOfNodes return vnode} Thank you for your reading, the above is the content of "how to use VNode in Vue 3.0 Advanced". After the study of this article, I believe you have a deeper understanding of how to use VNode in Vue 3.0, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.