vue自定义指令合集(超实用!)
作者:思考的行者
一、什么是自定义指令
vue官方提供很多指令,如:v-model,v-show,v-if,v-if等,他们都以v-开头。当这些指令不能满足我们实际开发需求时,我们还可以自定义指令。自定义指令主要分为全局自定义指令和局部自定义指令。
二、全局自定义指令directive
在main.js中写全局自定义指令
// 自动获取焦点 Vue.directive('focus', { inserted: function (el) { el.focus() } })
三、局部自定义指令directives
可以在任意组件中定义自定义指令,directives是一个对象,他的每一个属性就只一个自定义指令,这里定义了一个focus指令。
directives: { focus: { inserted: function (el) { el.focus() } } }
四、自定义指令的调用
和普通指令的使用方式一样v-自定义指令名称
如v-focus
五、自定义指令的钩子函数
有以下五个钩子函数:
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
每个钩子函数有以下参数:
- el:指令所绑定的元素,可以用来直接操作 DOM。
- binding:一个对象,包含以下 property:
- name:指令名,不包括 v- 前缀。
- value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
- expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
- arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
- modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
- vnode:Vue 编译生成的虚拟节点。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
注意:bind和insert都只调用一次;bind在insert前执行,也就是bind在dom树绘制前调用,insert在dom树绘制后调用;涉及dom操作的,我们一般都用insert,如自动获取焦点指令,只能用insert函数。
六、自定义指令传参
<div v-test:[data1]>这是测试页。。。。</div>
可以用binding.arg去接收":"后的参加参数,这里传递了data1这个变量,data1必须用[]包裹,否则就是‘data1’这个字符串,[]中只能传递一个变量,多个变量可以用对象或数组组装。binding.value去接收"="后的参数,这里是个函数所以用bingding.value()去调用。
<div v-test:[data1]='func'>这是测试页。。。。</div> test: { inserted(el, binding, vnode) { // 获取参数 console.log('test',binding.arg); // 执行传递的函数 binding.value({success: true,data:{}}); }, }
七、常见自定义指令
1、拖拽
dragV: { bind(drag, binding, vNode) { drag.style.position = 'absolute'; drag.style.zIndex = '9999'; //当鼠标按下时 drag.onmousedown = e => { //做到浏览器兼容 e = e || window.event let diffX = e.clientX - drag.offsetLeft let diffY = e.clientY - drag.offsetTop //当拉着box移动时 document.onmousemove = e => { // 浏览器兼容 e = e || window.event; let left = e.clientX - diffX; let top = e.clientY - diffY; drag.style.left = left + 'px'; drag.style.top = top + 'px'; } // 当鼠标抬起时 document.onmouseup = function() { this.onmousemove = null this.onmouseup = null } } } },
2、防抖
<div v-debounce:[time]="debounceFunc">这是测试页。。。。</div> debounce:{ inserted(el, binding) { let timer; let delay = binding.arg || 500; el.addEventListener('click', () => { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { binding.value() }, delay) }) }, }
八. 应用场景
8.1 自动获取焦点(官方示例)
// 注册一个全局自定义指令 `v-focus` Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el) { // 聚焦元素 el.focus() } })
8.2 一键 Copy的功能
- 首先建一个 js 文件(v-copy.js)。定义一个对象。( 指令实际就是一个对象 )
import { Message } from 'ant-design-vue'; const vCopy = { // 名字爱取啥取啥 /* bind 钩子函数,第一次绑定时调用,可以在这里做初始化设置 el: 作用的 dom 对象 value: 传给指令的值,也就是我们要 copy 的值 */ bind(el, { value }) { el.$value = value; // 用一个全局属性来存传进来的值,因为这个值在别的钩子函数里还会用到 el.handler = () => { if (!el.$value) { // 值为空的时候,给出提示,我这里的提示是用的 ant-design-vue 的提示,你们随意 Message.warning('无复制内容'); return; } // 动态创建 textarea 标签 const textarea = document.createElement('textarea'); // 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域 textarea.readOnly = 'readonly'; textarea.style.position = 'absolute'; textarea.style.left = '-9999px'; // 将要 copy 的值赋给 textarea 标签的 value 属性 textarea.value = el.$value; // 将 textarea 插入到 body 中 document.body.appendChild(textarea); // 选中值并复制 textarea.select(); // textarea.setSelectionRange(0, textarea.value.length); const result = document.execCommand('Copy'); if (result) { Message.success('复制成功'); } document.body.removeChild(textarea); }; // 绑定点击事件,就是所谓的一键 copy 啦 el.addEventListener('click', el.handler); }, // 当传进来的值更新的时候触发 componentUpdated(el, { value }) { el.$value = value; }, // 指令与元素解绑的时候,移除事件绑定 unbind(el) { el.removeEventListener('click', el.handler); }, }; export default vCopy;
总结
到此这篇关于vue自定义指令的文章就介绍到这了,更多相关vue自定义指令内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!