8个非常实用的Vue自定义指令
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8个非常实用的Vue自定义指令相关的知识,希望对你有一定的参考价值。
参考技术A 在 Vue,除了核心功能默认内置的指令 ( v-model 和 v-show ),Vue 也允许注册自定义指令。它的作用价值在于当开发人员在某些场景下需要对普通 DOM 元素进行操作。Vue自定义指令有全局注册和局部注册两种方式。先来看看注册全局指令的方式,通过 Vue.directive( id, [definition] ) 方式注册全局指令。然后在入口文件中进行 Vue.use() 调用。
批量注册指令,新建 directives/index.js 文件
在 main.js 引入并调用
指令定义函数提供了几个钩子函数(可选):
下面分享几个实用的 Vue 自定义指令
需求:实现一键复制文本内容,用于鼠标右键粘贴。
思路:
使用:给 Dom 加上 v-copy 及复制的文本即可
需求:实现长按,用户需要按下并按住按钮几秒钟,触发相应的事件
思路:
使用:给 Dom 加上 v-longpress 及回调函数即可
背景:在开发中,有些提交保存按钮有时候会在短时间内被点击多次,这样就会多次重复请求后端接口,造成数据的混乱,比如新增表单的提交按钮,多次点击就会新增多条重复的数据。
需求:防止按钮在短时间内被多次点击,使用防抖函数限制规定时间内只能点击一次。
思路:
使用:给 Dom 加上 v-debounce 及回调函数即可
背景:开发中遇到的表单输入,往往会有对输入内容的限制,比如不能输入表情和特殊字符,只能输入数字或字母等。
我们常规方法是在每一个表单的 on-change 事件上做处理。
这样代码量比较大而且不好维护,所以我们需要自定义一个指令来解决这问题。
需求:根据正则表达式,设计自定义处理表单输入规则的指令,下面以禁止输入表情和特殊字符为例。
使用:将需要校验的输入框加上 v-emoji 即可
背景:在类电商类项目,往往存在大量的图片,如 banner 广告图,菜单导航图,美团等商家列表头图等。图片众多以及图片体积过大往往会影响页面加载速度,造成不良的用户体验,所以进行图片懒加载优化势在必行。
需求:实现一个图片懒加载指令,只加载浏览器可见区域的图片。
思路:
图片懒加载有两种方式可以实现,一是绑定 srcoll 事件进行监听,二是使用 IntersectionObserver 判断图片是否到了可视区域,但是有浏览器兼容性问题。
下面封装一个懒加载指令兼容两种方法,判断浏览器是否支持 IntersectionObserver API,如果支持就使用 IntersectionObserver 实现懒加载,否则则使用 srcoll 事件监听 + 节流的方法实现。
使用,将组件内 标签的 src 换成 v-LazyLoad
背景:在一些后台管理系统,我们可能需要根据用户角色进行一些操作权限的判断,很多时候我们都是粗暴地给一个元素添加 v-if / v-show 来进行显示隐藏,但如果判断条件繁琐且多个地方需要判断,这种方式的代码不仅不优雅而且冗余。针对这种情况,我们可以通过全局自定义指令来处理。
需求:自定义一个权限指令,对需要权限判断的 Dom 进行显示隐藏。
思路:
使用:给 v-permission 赋值判断即可
需求:给整个页面添加背景水印
思路:
使用,设置水印文案,颜色,字体大小即可
需求:实现一个拖拽指令,可在页面可视区域任意拖拽元素。
思路:
使用: 在 Dom 上加上 v-draggable 即可
Vue_(组件)自定义指令
Vue.js自定义指令 传送门
自定义指令:除了内置指令,Vue也允许用户自定义指令
注册指令:通过全局API Vue.directive可以注册自定义指令
自定义指令的钩子函数参数:自定义指令的钩子函数可以传递4个参数,分别是el、binding、vnode、oldVnode
Learn
一、自定义指令钩子函数
二、自定义指令钩子函数的参数
三、自定义指令简写
项目结构
【每个demo下方都存有html源码】
一、自定义指令钩子函数 传送门
自定义指令的钩子函数:
bind:只调用一次,指令第一次绑定到元素时调用
inserted:被绑定元素插入父节点时调用
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
unbind:只调用一次,指令与元素解绑时调用
自定义指令的使用:在自定指令的名称前加 上 v-;
通过button点击按钮来控制是否解除绑定
<div id="GaryId"> <input type="text" v-model="name"/><br /> name:<span v-if="flag" v-demo ref=‘name‘>{{name}}</span><br /> <button @click="flag=!flag">解除绑定</button> </div>
Vue.directive(‘demo‘,{ //指令的钩子函数 bind(){ alert("bind 首次绑定到元素时候执行,执行一次,常用于数据的初始化操作"); }, inserted(){ alert("instered 插入到父节点之后,DOM对象"); }, unbind(){ alert("unbind 解除绑定"); }, update(){ alert("updata 绑定该指令的元素 所在的Vue实例挂载的DOM树 发生更新时候调用"+"name ="+vm.$refs.name.textContent); }, componentUpdated(){ alert("componentUpdated 更新后调用"+"name ="+vm.$refs.name.textContent); } });
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Gary</title> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <div id="GaryId"> <input type="text" v-model="name"/><br /> name:<span v-if="flag" v-demo ref=‘name‘>{{name}}</span><br /> <button @click="flag=!flag">解除绑定</button> </div> </body> <script> Vue.directive(‘demo‘,{ //指令的钩子函数 bind(){ alert("bind 首次绑定到元素时候执行,执行一次,常用于数据的初始化操作"); }, inserted(){ alert("instered 插入到父节点之后,DOM对象"); }, unbind(){ alert("unbind 解除绑定"); }, update(){ alert("updata 绑定该指令的元素 所在的Vue实例挂载的DOM树 发生更新时候调用"+"name ="+vm.$refs.name.textContent); }, componentUpdated(){ alert("componentUpdated 更新后调用"+"name ="+vm.$refs.name.textContent); } }); let vm = new Vue({ data:{ name:‘Gary‘, flag:true } }).$mount(‘#GaryId‘); </script> </html>
二、自定义指令钩子函数的参数 传送门
自定义指令的钩子函数参数:自定义指令的钩子函数可以传递4个参数,分别是el、binding、vnode、oldVnode;
el:获取DOM对象;
binding:一个包含很多属性的对象;
vnode:Vue编译生成的虚拟节点;
oldVnode:上一个虚拟节点;
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Gary</title> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <div id="GaryId"> <input type="text" v-model="name" /><br /> name : <span v-demo.once.stop=‘name‘ ref=‘name‘>{{name}}</span><br /> <button v-on:click="flag = !flag">click </body> <script> Vue.directive(‘demo‘,{ //指令的钩子函数 bind(el,binding){ //console.log(el); el.style.color=‘red‘; console.log(binding.name); console.log(binding.value); console.log(binding.expression); console.log(binding.arg); console.log(binding.modifiers); if(binding.arg === ‘click‘){ console.log("执行点击事件"); } if(binding.modifiers.once){ console.log("只执行一次"); } }, update(el,binding){ console.log("update value = "+binding.value); console.log("update oldValue = "+binding.oldValue); } }); let vm = new Vue({ data:{ name:‘Gary‘, flag:true } }).$mount(‘#GaryId‘); </script> </html>
三、自定义指令简写 传送门
通过directives指令和focus指令实现修改样式和加载页面时自动聚焦
<div id="GaryId"> <!--通过v-focus标签,当页面加载时,自动聚焦到这个表单上--> <input type="text" v-model="name" v-focus/><br /> name : <span v-font_style:blue>{{name}}</span><br /> </body>
directives : { font_style : function(el, binding){ el.style.color = binding.arg; }, //聚焦 focus:{ inserted(el){ el.focus(); } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Gary</title> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <div id="GaryId"> <!--通过v-focus标签,当页面加载时,自动聚焦到这个表单上--> <input type="text" v-model="name" v-focus/><br /> name : <span v-font_style:blue>{{name}}</span><br /> </body> <script> let vm = new Vue({ data : { name : ‘Gary‘, flag : true }, directives : { font_style : function(el, binding){ el.style.color = binding.arg; }, focus : { inserted(el){ el.focus(); } } } }).$mount(‘#GaryId‘); </script> </html>
以上是关于8个非常实用的Vue自定义指令的主要内容,如果未能解决你的问题,请参考以下文章