vue3 语法,vue3使用
在计算机技术中,指令是由指令集架构定义的单个的中央处理器操作,在更广泛的意义上,"指令"可以是任何可执行程序的元素的表述,例如字节码,下面这篇文章主要给大家介绍了关于Vue3指令是如何实现的相关资料,需要的朋友可以参考下
目录
前言指令注册全局注册组件内注册指令搜寻指令搜寻的时机指令搜寻的逻辑指令绑定虚拟节点指令调用关于指令的思考组件上使用指令组件上的一些使用场景总结
前言
某视频剪辑软件指令是指对普通数字正射影像图元素进行底层操作的射流研究…对象,它们会被挂在元件虚拟节点对象上,在元件虚拟节点的一些生命周期中会被调用,从而可以操作元件虚拟节点的底层数字正射影像图元素。
指令注册
指令注册是指将指令对应的射流研究…代码放置在某些地方,需要使用的时候可以在这些地方进行查找。
全局注册
全局注册是调用app.directive(指令名称, { 指令代码}) 来实现的app.directive(pin ,(el,binding)={
el.style.position=fixed
const s=binding.arg top
el.style[s]=binding.value px
})
全局注册的逻辑是将指令名称和对应的指令代码挂载在全局的语境的指令对象上!- apiCreateApp.js -
指令(名称:字符串,指令?指令){
//挂载在全局的`背景的`指示对象上
语境。指令[名称]=指令
返回应用程序
},
组件内注册
组件内注册是在组件内添加指令的选项指令:{
pin: (el,binding)={
el.style.position=fixed
const s=binding.arg top
el.style[s]=binding.value px
}
}
组件注册的逻辑是将指令名称和对应的指令代码挂载在组件实例对象的指令上!-组件。ts -
导出函数应用选项(实例:ComponentInternalInstance) {
//挂载在组件实例对象的`指示上
instance .指令=指令
}
指令搜寻
指令搜寻的时机
开发者是在模板中使用指令,所以应该是在模板渲染的时候需要先搜寻到对应的指令。
不使用指令的模板h4指令演示/h4渲染函数如下:
函数渲染(_ctx,_cache) {
带有(_ctx) {
const { openBlock: _openBlock,createElementBlock:_ createElementBlock }=_ Vue
return (_openBlock(),_createElementBlock(h4 ,null,指令演示))
}
}
使用指令的模板h4 v形销:[右]=20 指令演示/h4渲染函数如下:
函数渲染(_ctx,_cache) {
带有(_ctx) {
const { createTextVNode:_ createTextVNode,resolve directive:_ resolve directive,withDirectives: _withDirectives,openBlock: _openBlock,createElementBlock:_ createElementBlock }=_ Vue
const _ directive _ pin=_ resolved指令( pin )
return _ with指令((_ open block(),_createElementBlock(h4 ,null,_ hoisted _,512 /* NEED_PATCH */)),[
[_directive_pin,pinPadding,direction]
])
}
}
使用指令的模板需要先搜寻对应的指令,然后绑定指令到虚拟节点
指令搜寻的逻辑
指令搜寻的逻辑是先从组件实例情况的指令上寻找,如果没找到再在上下文的指令上寻找导出函数resolveDirective(名称:字符串):指令未定义{
返回resolveAsset(指令,名称)
}
函数resolveAsset(
类型:资产类型,
名称:字符串,
warnMissing=true,
maybeSelfReference=false
) {
const res=
//本地注册
//首先检查为选项应用程序接口解析的实例[类型]
resolve(实例[类型] (组件作为组件选项)[类型],名称)
//全局注册
解决(实例。应用程序上下文[类型],名称)
返回资源
}
指令绑定VNode
带有导演的导出函数扩展了虚拟节点(
vnode: T,
指令:指令参数
):T {
const bindings:指令binding[]=vnode。dirs (vnode。dirs=[])
对于(设I=0;一。指令长度;i ) {
设[目录,值,参数,修饰符=EMPTY_OBJ]=指令[我]
if (isFunction(dir)) {
dir={
已安装:目录,
更新:目录
}作为对象指令
}
bindings.push({
dir,
实例,
值,
旧值:空0,
arg,
修饰语
})
}
返回虚拟节点
}
将每个指令目录和其他一些参数挂载在虚拟节点的显示目录记录上。其他参数是:实例组件实例,值指令的新值(本例为20),旧值指令的旧值(本例为0),参数指令的参数(本例为右)
指令调用
指令调用是指指令的代码什么时候被执行的?我们最开始提到指令是对普通DOM元素进行底层操作的JS对象,所以指令的逻辑应该是在Element VNode中进行处理的。
const mountElement=(
vnode: VNode,
容器:RendererElement,
anchor: RendererNode null,
父组件:组件内部实例空,
父挂起:suspendeboundary null,
isSVG:布尔型,
slotScopeIds: string[] null,
优化:布尔型
)={
//1
if (dirs) {
invokeDirectiveHook(vnode,null,parentComponent, created )
}
//2
if (dirs) {
invokeDirectiveHook(vnode,null,parentComponent, beforeMount )
}
//3
queuepostrendeffect(()={
vnode hook invokenodehook(vnode hook,parentComponent,vnode)
needCallTransitionHooks过渡!回车(el)
dirs invokeDirectiveHook(vnode,null,parentComponent, mounted )
},父悬念)
}
const patchElement=(
n1: VNode,
n2: VNode,
父组件:组件内部实例空,
父挂起:suspendeboundary null,
isSVG:布尔型,
slotScopeIds: string[] null,
优化:布尔型
)={
const el=(n2.el=n1.el!)
//1
if (dirs) {
invokeDirectiveHook(n2,n1,parentComponent, beforeUpdate )
}
//2
queuepostrendeffect(()={
虚拟节点挂钩invokenodehook(虚拟节点挂钩,父组件,n2,n1)
目录invokeDirectiveHook(n2,n1,parentComponent,’已更新)
},父悬念)
}
const unmount: UnmountFn=(
vnode,
parentComponent,
家长悬念,
doRemove=false,
优化=假
)={
常数{
类型,
道具,
裁判,
孩子们,
动态儿童,
形状标志
补丁标志
显示目录记录
}=vnode
//取消设置引用
if (ref!=null) {
setRef(ref,null,parent悬念,vnode,真)
}
if (shapeFlag ShapeFlags .COMPONENT_SHOULD_KEEP_ALIVE) {
;(parentComponent!中强作为KeepAliveContext).停用(vnode)
返回
}
const shouldInvokeDirs=形状标志形状标志.元素目录
let vnode hook:vnode hook undefined null
if((vnode hook=props道具。卸载前的on node)){
invokeVNodeHook(vnodeHook,parentComponent,vnode)
}
if (shapeFlag ShapeFlags .组件){
卸载组件(vnode.component!父悬念,doRemove)
}否则{
if (shouldInvokeDirs) {
invokeDirectiveHook(vnode,null,parentComponent, beforeUnmount )
}
queuepostrendeffect(()={
vnode hook invokenodehook(vnode hook,parentComponent,vnode)
shouldInvokeDirs
invokeDirectiveHook(vnode,null,parentComponent, unmounted )
},父悬念)
}
在挂载元素虚拟节点的时候,会调用指令的创建,安装前和安装好的钩子函数;
在更新元素虚拟节点的时候,会调用指令的更新前,已更新钩子函数;
在卸载元素虚拟节点的时候,会调用指令的卸载前,已卸载钩子函数;
关于指令的思考
组件上使用指令
我们上面提到了指令是作用在元素VNode上的,那组件使用指令(例如son v-pin:[右]= 20 /子)是什么效果呢?结果是组件上使用的指令会作用在组件内部的根节点的元素VNode上。
导出函数renderComponentRoot(
实例:组件内部实例
):VNode {
常数{
类型:组件,
vnode,
代理人,
使用代理,
道具,
建议:[建议],
插槽,
attrs,
发射,
渲染,
renderCache,
数据,
setupState,
ctx,
继承人
}=实例
//继承指令
if (vnode.dirs) {
if (__DEV__!isElementRoot(root)) {
警告(
`在具有非元素根节点的组件上使用了运行时指令。`
`指令将无法按预期发挥作用。
)
}
root.dirs=root.dirs?root . dirs . concat(vnode . dirs):vnode . dirs
}
}
当组件呈现子树VNode的根VNode时,组件的指令dir将被添加到VNode的根元素的dir中。因此,作用于组件的指令等同于作用于根节点的元素VNode的指令。
组件上的一些使用场景
我认为更常用的指令的一些使用场景是:
V-lazyload:图片懒加载v-loading:增加一个加载动画v-permission:权限控制,隐藏DOM元素v-无权限去抖:输入防抖,尤其是搜索框请求的输入。
总结
这就是关于如何实现Vue3指令的这篇文章。有关Vue3指令实现的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。