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

vue自定义指令的使用~以模仿v-show和实现v-copy为例,讲解

时间:2023-03-31 15:43:44 vue.js

.item{margin-top:12px;字体大小:24px;字体粗细:更粗;cursor:pointer;}vue自定义指令的背景。我们知道,前端程序员编写的各种代码最终都会应用到页面上。DOM元素。比如用HTML固定DOM的基本结构,用CSS设置DOM的样式,用JS做一些DOM交互。因为DOM元素相当于“物理层”,应该呈现给用户。DOM相当于一个积木。我们操作这个积木块,最后把它“搭建”成各种效果。所以所有花哨的前端框架都是基于HTML、CSS、JS前端三件套来封装的。所以在jQuery中通过$字符直接操作DOM是非常方便的。回流重绘会稍微浪费浏览器的性能,页面容易卡顿,导致用户体验不佳。凡事有利有弊,直接操作DOM,有时候,可能是一种简单、方便、快捷的选择。于是vue和react就登场了。使用数据驱动的思想,不是直接操作DOM,而是通过虚拟DOM做一个buffer。虚拟DOM会收集谁需要操作DOM,以及DOM中有哪些东西被操作过。先记录一下。最后,他们一起操作DOM。有点像js文档碎片化。在这种情况下,浏览器的性能会得到优化和提升很多。所以vue中不提倡直接操作DOM,因为有虚拟DOM,为什么要直接操作真实的DOM呢?使用vue命令,虚拟DOM真是个好东西,点个赞。我们知道vue提供的内置指令非常方便,可以解决大部分DOM操作问题,但不能解决所有问题。那么在某些情况下,Vue内置的指令并不能满足我们的需求,那我们该怎么办呢?当然Vue的创始人也想到了这个问题,于是他创建了一个vue自定义命令,里面封装了一套钩子函数和相应的参数规则供我们使用,这样就可以更方便的解决相应的问题。vue自定义命令是直接对DOM进行操作的。在某些场景下,vue自定义指令是一个不错的选择。vue自定义指令有两种:1.全局自定义指令(需要全局注册)2.组件自定义指令(需要组件内部注册)自定义指令其实就是一个对象,上面有一些钩子函数目的。自定义指令对象上的钩子函数类似于Vue组件的生命周期钩子函数。后续会通过案例来说明全局自定义指令的一般使用。多了,毕竟复用vue自定义指令方便。案例1el-input初始获得焦点(组件自定义说明)这个案例其实是官网的一个案例。这里我们修改一下,方便我们理解。假设我们需要这样一个效果:页面加载后,el-input输入框自动获得焦点,类似于打开百度页面后输入框自动获得焦点。如果要演示,直接复制粘贴代码即可。案例二模仿v-show函数(全局自定义命令)效果图。请看下面的效果图。功能其实和v-show没有区别。举这样一个例子,方便更好的理解vue自定义指令。第一步是创建一个新的utils文件夹来存储index.js文件。该文件用于编写全局自定义指令//importvue并使用vue的directive方法注册自定义指令importVuefrom'vue'Vue.directive('showshow',{//指令名称为showshow//bind函数一般用于初始化数据,也可以绑定事件bind(el,binding,vnode){console.log(el,binding.value,vnode);//el参数为的元素当前使用的命令,bind参数为命令绑定的数据,vnode为虚拟domconstflag=binding.value//查找组件中绑定的flagif(flag==false){el.style.display='无'}else{el.style.display='inline-block'}},//inserted函数是调用inserted(el,binding,vnode){},//update和componentUpdated用于更新,但前者更常用,oldVnode参数只用在这两个会有componentUpdated(el,binding,vnode,oldVnode){},update(el,binding,vnode,oldVnode){constflag=binding.valueif(flag==false){el.style.display='none'}else{el.style.display='inline-block'}},//unbindunbind时使用,比如移除第一个bind中绑定的事件functionunbind(el,binding,vnode){}});第二步,在main.js中引入这个用于编写全局自定义指令的文件(意思是使用它)importVuefrom'vue'importAppfrom'./App.vue'importrouterfrom"@/router/index.js"//引入路由表importstorefrom'./store/index'//引入vuex//...//引入即可使用全局自定义指令^_^import'./views/utils/index.js'letvvvue=newVue({render:h=>h(App),router,store//mountup}).$mount('#app')第三步在组件中使用全局自定义命令是道友说的吧?这不是多余的吗?其实不是,因为我没有遇到过具体的场景。以上两个例子主要是学习自定义指令的思想。接下来举个小例子,点击文字一键复制功能。案例3实现v-copy自定义命令的渲染点击复制成功,然后在电脑相应位置执行CtrlV直接粘贴点击的文字。第一步是编写自定义命令代码importVuefrom'vue'Vue.directive('copy',{//指令的名称是v-copy//bind函数初始化bind(el,binding,vnode){},//inserted函数调用inserted(元素插入dom节点时的el,binding,vnode){//el参数为当前使用命令的元素,bind参数为绑定的数据命令,vnode为虚拟dom//将copyFn函数挂在el上,方便使用el.copyFn=()=>{console.log('点击了哪个DOM',el);//创建选中范围varrange=document.createRange();//选择被点击的domrange.selectNode(el);//移除剪贴板如果不加这条语句,则无法在ie和Edge中复制window.getSelection().removeAllRanges();//将el中的文本内容复制到剪贴板window.getSelection().addRange(range);//启用复制粘贴功能letflag=document.execCommand('copy');//支付注意补偿可用性问题标志?alert('复制成功,可以粘贴'):alert('当前浏览器不支持一键复制功能,请手动复制粘贴')}el.addEventListener('click',el.copyFn)},//更新和componentUpdated用于更新,但前者更常用//oldVnode参数只会在这两个hook中可用,更新后会有更新前后的DOMcomponentUpdated(el,binding,vnode,oldVnode){console.log('componentUpdated');},update(el,binding,vnode,oldVnode){console.log('update');},//unbindunbind时使用,比如移除unbind中绑定的第一个bind函数Events(el,binding,vnode){el.removeEventListener('click',el.copyFn)}});/***为了快速上手自定义命令钩子,我们可以这样简单理解**bind和insertedhooks-->类似于createdandmountedhooks*componentUpdatedandupdatehooks-->类似于updatedhooks*类似于unbindhooks-->destroyedhooks**可以复制代码运行后打印出来it,比较详细方便准确理解**/第二步使用.item{margin-top:12px;字体大小:24px;字体粗细:更粗;cursor:pointer;}补充案例中的知识范围对象:https://developer.mozilla.org...选择对象:https://developer.mozilla.org...execCommand方法:https://developer.mozilla.org...关于MDN,execCommand方法以后可能会删掉,四物上有很好的回答,顺便也粘贴一下:https://segmentfault.com/q/10。..总结什么时候需要使用自定义指令?当内置指令不够用时,当需要做一些特效时,当需要对普通DOM元素进行低级操作时,自定义指令接近原生js的写法,我们使用它的hooks合理地函数和相应的参数可以实现更灵活的效果功能。毕竟Vue虽然提供了很多内置的指令,方便我们直接使用,快速上手,但是也限制了程序员的一些发散思维。各有优缺点,需要权衡一下^_^