Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement the Vue3 instruction

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Today, I would like to share with you the relevant knowledge of how the Vue3 instruction is realized. The content is detailed and the logic is clear. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.

Preface

Vue instructions are JS objects that perform low-level operations on ordinary DOM elements, which are hung on Element VNode objects and called in some life cycles of Element VNode, so that they can manipulate the underlying DOM elements of Element VNode.

Instruction registration

Instruction registration means that the JS code corresponding to the instruction is placed in certain places where it can be looked up when needed.

Global registration

Global registration is achieved by calling app.directive ('instruction name', {instruction code})

App.directive ('pin', (el, binding) = > {el.style.position =' fixed' const s = binding.arg | | 'top' el.style [s] = binding.value +' px'})

The logic of global registration is to mount the instruction name and the corresponding instruction code on the global context directives object

Directive (name: string, directive?: Directive) {/ / Mount context.directives [name] = directive return app} on the global `context` `directives` object and register within the component

Registration within a component is an option to add directives within a component

Directives: {pin: (el, binding) = > {el.style.position = 'fixed' const s = binding.arg | |' top' el.style [s] = binding.value + 'px'}}

The logic of component registration is to mount the instruction name and the corresponding instruction code on the directives of the component instance object

Export function applyOptions (instance: ComponentInternalInstance) {/ / Mount on the assembly instance object `directives` instance.directives = directives} instruction search timing

The developer uses the instructions in the template, so you should first search for the corresponding instructions when rendering the template.

The template command that does not use the command demonstrates the rendering function as follows:

Function render (_ ctx, _ cache) {with (_ ctx) {const {openBlock: _ openBlock, createElementBlock: _ createElementBlock} = _ Vue return (_ openBlock (), _ createElementBlock ("h5", null, "instruction demonstration"))}}

Use the template instruction of the command to demonstrate the rendering function as follows:

Function render (_ ctx, _ cache) {with (_ ctx) {const {createTextVNode: _ createTextVNode, resolveDirective: _ resolveDirective, withDirectives: _ withDirectives, openBlock: _ openBlock, createElementBlock: _ createElementBlock} = _ Vue const _ directive_pin = _ resolveDirective ("pin") return _ withDirectives ((_ openBlock (), _ createElementBlock ("h5", null, _ hoisted_2, 512 / * NEED_PATCH * /)), [[_ directive_pin, pinPadding, direction])}}

The template that uses the instruction needs to search for the corresponding instruction, and then bind the instruction to VNode

Logic of instruction search

The logic of instruction search is to look for it on the directives of the component instance instance, and then on the directives of appContext if it is not found.

Export function resolveDirective (name: string): Directive | undefined {return resolveAsset (DIRECTIVES, name)} function resolveAsset (type: AssetTypes, name: string, warnMissing = true, maybeSelfReference = false) {const res = / / local registration / / check instance [type] first which is resolved for options API resolve (instance [type] | | (Component as ComponentOptions) [type], name) | / / global registration resolve (instance.appContext [type], name) return res} instruction to bind VNodeexport function withDirectives (vnode: t Directives: DirectiveArguments): t {const bindings: DirectiveBinding [] = vnode.dirs | | (vnode.dirs = []) for (let I = 0) I

< directives.length; i++) { let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i] if (isFunction(dir)) { dir = { mounted: dir, updated: dir } as ObjectDirective } bindings.push({ dir, instance, value, oldValue: void 0, arg, modifiers }) } return vnode} 将每个指令dir和其他一些参数 挂载在 VNode的dirs上。 其他参数是: instance组件实例, value指令的新值(本例为20),oldValue指令的旧值(本例为0),arg指令的参数(本例为right) 指令调用 指令调用是指 指令的代码什么时候被执行的? 我们最开始提到指令是对普通DOM元素进行底层操作的JS对象,所以指令的逻辑应该是在 Element VNode中进行处理的。 const mountElement = ( vnode: VNode, container: RendererElement, anchor: RendererNode | null, parentComponent: ComponentInternalInstance | null, parentSuspense: SuspenseBoundary | null, isSVG: boolean, slotScopeIds: string[] | null, optimized: boolean) =>

{/ / 1 if (dirs) {invokeDirectiveHook (vnode, null, parentComponent, 'created')} / / 2 if (dirs) {invokeDirectiveHook (vnode, null, parentComponent,' beforeMount')} / / 3 queuePostRenderEffect (() = > {vnodeHook & & invokeVNodeHook (vnodeHook, parentComponent, vnode) needCallTransitionHooks & & substitution.enter (el) dirs & & invokeDirectiveHook (vnode, null, parentComponent, 'mounted')} ParentSuspense)} const patchElement = (N1: VNode, N2: VNode, parentComponent: ComponentInternalInstance | null, parentSuspense: SuspenseBoundary | null, isSVG: boolean, slotScopeIds: string [] | null, optimized: boolean) = > {const el = (n2.el = n1.el!) / / 1 if (dirs) {invokeDirectiveHook (N2, N1, parentComponent, 'beforeUpdate')} / / 2 queuePostRenderEffect (() = > {vnodeHook & invokeVNodeHook (vnodeHook, parentComponent, N2, N1) dirs & & invokeDirectiveHook (N2, N1) ParentComponent, 'updated')}, parentSuspense)} const unmount: UnmountFn = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) = > {const {type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs} = vnode / / unset ref if (ref! = null) {setRef (ref, null, parentSuspense, vnode, true)} if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) { (parentComponentroom.ctx as KeepAliveContext) .deactivate (vnode) return} const shouldInvokeDirs = shapeFlag & ShapeFlags.ELEMENT & & dirs let vnodeHook: VNodeHook | undefined | null if ((vnodeHook = props & & props.onVnodeBeforeUnmount)) {invokeVNodeHook (vnodeHook, parentComponent, vnode)} if (shapeFlag & ShapeFlags.COMPONENT) {unmountComponent (vnode.inventments, parentSuspense, doRemove)} else {if (shouldInvokeDirs) {invokeDirectiveHook (vnode, null, parentComponent) 'beforeUnmount')} queuePostRenderEffect (() = > {vnodeHook & & invokeVNodeHook (vnodeHook, parentComponent, vnode) shouldInvokeDirs & & invokeDirectiveHook (vnode, null, parentComponent,' unmounted')}, parentSuspense)}

When the element VNode is mounted, the instruction's created, beforeMount, and mounted hook functions are called

When the element VNode is updated, the instruction's beforeUpdate, updated hook functions are called

When the element VNode is unloaded, the instruction's beforeUnmount, unmounted hook functions are called

Using instructions on the thinking component of instructions

We mentioned above that instructions act on the element VNode, so what is the effect of components using instructions (for example)? The result is that the instructions used on the component act on the element VNode of the root node within the component.

Export function renderComponentRoot (instance: ComponentInternalInstance): VNode {const {type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx InheritAttrs} = instance / / inherit directives if (vnode.dirs) {if (_ _ DEV__ & &! isElementRoot (root)) {warn (`Runtime directive used on component with non-element root node. `+ `The directives will not function as intended.`)} root.dirs = root.dirs? Root.dirs.concat (vnode.dirs): vnode.dirs}}

When the component renders the root VNode of the subtree VNode, the component's instruction dirs is added to the dirs of the root element VNode. So the instruction that acts on the component is equivalent to the element VNode that acts on the root node.

Some usage scenarios on components

I think the usage scenarios of some of the more commonly used instructions are:

V-lazyload: lazy loading of pictures

V-loading: implement to add a load animation

V-permission: permission control. Hide DOM elements without permissions.

V-debounce: input anti-shake, especially the input requested by the search box

These are all the contents of the article "how to implement the Vue3 instruction". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report