当前位置: 首页 > Web前端 > vue.js

Vue3自定义指令开发

时间:2023-04-01 01:27:15 vue.js

什么是指令?Angular和Vue都有Directive的概念。我们通常把Directive翻译成“指令”。在计算中,指令是由指令集体系结构定义的单个CPU操作。在更广泛的意义上,“指令”可以是可执行程序的任何元素的表示,例如字节码。那么前端框架Vue中的“命令”到底是什么,它有什么作用呢?在Vue开发中,我们经常在模板中使用v-开头的关键字,比如v-model、v-show。这些关键字是Vue框架内置的指令。通过使用v-model,可以实现DOM与数据的绑定;通过使用v-show,您可以控制DOM元素的显示。简而言之,就是通过使用这些模板上的标签,让框架对DOM元素进行指定的处理,同时在DOM变化后,框架可以同时更新指定的数据。指令是VueMVVM的基础之一。指令使用场景Vue除了使用内置指令外,还支持自定义指令。通过自定义指令可以考虑以下场景:DOM的基本操作。当组件中的某些处理无法用现有指令实现时,可以实现自定义指令。.比如组件水印,自动对焦。与使用ref获取DOM操作相比,封装指令更符合MVVM架构,M和V不直接交互。亮黄色高亮这段文字

多个组件可用的通用操作可以通过组件(Component)很好的复用,功能也可以通过组件实现复用在成分。比如拼写检查,图片懒加载。使用组件,只要给需要拼写检查的输入组件加上标签,就可以一次性给组件注入拼写检查功能,不需要为不同的组件封装新的拼写支持功能。Vue3如何自定义指令Vue支持全局注册和本地注册指令。全局注册是通过app实例的directive方法注册的。letapp=createApp(App)app.directive('highlight',{beforeMount(el,binding,vnode){el.style.background=binding.value}})部分注册通过设置组件的directive属性注册导出默认defineComponent({name:"WebDesigner",components:{Designer,},directives:{highlight:{beforeMount(el,binding,vnode){el.style.background=binding.value;},},},});registercomponents包含组件的名称,需要唯一,是组件的实现对象。分组后,它可以用在任何元素上。亮黄色高亮这段文字

自定义组件是实现Vue提供的钩子功能。Vue3中钩子函数的生命周期类似于组件的生命周期:created-在元素已经被创建,但是属性和事件还没有生效之后被调用。beforeMount-仅在指令首次绑定元素时调用一次。mounted-当元素被插入父元素时调用。beforeUpdate:在元素本身更新之前调用Updated-在元素或子元素更新之后调用。beforeUnmount:在元素被卸载之前调用。unmounted-指令时调用unmounted,每个钩子函数只调用一次都有如下参数:el:指令绑定的元素,可用于直接操作DOMbinding:数据对象,包含以下属性instance:当前的实例成分。一般建议指令与组件无关。如果需要使用组件上下文ViewModel,可以使用从这里获取value:指令的值,即上例中“黄色”oldValue:指令的前一个值,可以同beforeUpdate和Updated中的值。arg:传递给命令的参数,比如v-on:click中的click。修饰符:包含修饰符的对象。例如,v-on.stop:click可以获得一个{stop:true}对象。vnode:Vue编译生成的虚拟节点,prevVNode:Update时上一个虚拟节点。Vue2指令升级指令是Vue3中的一个BreakingChange。挂钩函数名称和指令数已更改。在Vue3中,为指令创建了更多的函数,函数名与组件的生命周期保持一致,更易于理解。以下是对变化的介绍。另一个变化是获取组件上下文对象的方式发生了变化。通常,建议指令和组件实例相互独立。从自定义指令内部访问组件实例可能表明这里不需要封装指令,指令是组件的功能。但是可能确实有一些场景是需要获取组件实例的。Vue2中通过vnode参数获取bind(el,binding,vnode){constvm=vnode.context}Vue3中通过binding参数获取mounted(el,binding,vnode){constvm=binding.instance}Vue3实例custominstruction–inputspellcheck这里使用Plugin来注入指令。新建一个SpellCheckPlugin.ts,声明插件,在插件的install方法中注入命令import{App}from'vue'functionSpellCheckMain(app:App,options:any){//}exportdefault{install:SpellCheckMain}该组件实现了SpellCheckMain方法以及,拼写检查方法,具体拼写检查规则可以根据业务实现或者使用其他插件方法实现functionSpellCheckMain(app:App,options:any){constSpellCheckAttribute="spell-check-el";letSpellCheckTimer:Map=newMap();letcheckerId=0;functioncheckElement(el:HTMLElement){letattr=el.getAttribute(SpellCheckAttribute);}如果(attr){clearTimeout(SpellCheckTimer.get(attr));让计时器=setTimeout(()=>{checkElementAsync(el)},500);SpellCheckTimer.set(attr,timer)}}functioncheckText(words?:string|null):\[string?\]{if(!words){返回\[\];}leterrorWordList:\[string?\]=\[\];尝试{让wordsList=words.match(/\[a-zA-Z\]+/ig);wordsList?.forEach((word)=>{if(!checkWord(word)){errorWordList.push(单词);}})}catch{}returnerrorWordList;}functioncheckWord(text:string){//模拟拼写检查,这里使用其他检查库returntext.length>6?false:true;}functioncheckElementAsync(el:HTMLElement){让文本=(el作为HTMLInputElement).value||el.innerText;让结果=检查文本(文本);让attr=el.getAttribute(SpellCheckAttribute);如果(!attr){返回;}if(result&&result.length){el.style.background="pink"letdiv=document.getElementById(attr);如果(!div){div=document.createElement("div");div.id=属性;div.style.position="absolute"div.style.top="0px"div.style.left=el.clientWidth+"px"if(el.parentElement){el.parentElement.style.position="relative"if(el.parentElement.lastChild===el){el.parent元素.appendChild(div);}else{el.parentElement.insertBefore(div,el.nextSibling);}}}div.innerHTML=result.length.toString()+"-"+result.join(",");}else{el.style.background="";让div=document.getElementById(attr);if(div){div.innerHTML=""}}console.log(result)}app.directive('拼写检查',{created(){console.log("created",arguments)},mounted:function(el,binding,vnode,oldVnode){console.log("mounted",arguments)//为父级设置检查器idletattr="spellcheck-"+(checkerId++);el.setAttribute(SpellCheckAttribute,attr);console.log("attr",attr)if(el.tagName.toUpperCase()==="DIV"){el.addEventListener("blur",function(){checkElement(el)},false);}如果(el.tagName.toUpperCase()==="INPUT"){el.addEventListener("keyup",function(){checkElement(el)},false);}//el.addEventListener("focus",function(){//checkElement(el)//},false);},更新:函数(el){console.log("componentUpdated",arguments)checkElement(el);},unmounted:function(el){console.log("unmounted",arguments)letattr=el.getAttribute(SpellCheckAttribute);如果(attr){让div=document.getElementById(attr);如果(div){div.remove();}}}})}main.ts中使用插件///import{createApp}from'vue'importAppfrom'./App.vue'importrouterfrom'./router'importSpellCheckPluginfrom'./plugins/SpellCheckPlugin'letapp=createApp(App)app.use(SpellCheckPlugin)app.use(router).mount('#app')组件中直接使用指令即可结合SpreadJS的使用,基于检查用户拼写输入的功能,效果如下图所示:以上是Vue3自定义命令开发的部分玩法介绍。如果你知道更多使用方法,欢迎留言分享。