1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Vue directive 自定义指令

Vue directive 自定义指令

时间:2023-01-07 08:01:24

相关推荐

Vue directive 自定义指令

Vue自定义指令一共有5个钩子函数,分别是:

bind、inserted、update、componentUpdate 、unbind

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind:只调用一次,指令与元素解绑时调用。

指令钩子函数会被传入以下参数:

el:指令所绑定的元素,可以用来直接操作 DOM。binding:一个对象,包含以下 property:name:指令名,不包括v-前缀。value:指令的绑定值,例如:v-my-directive="1 + 1"中,绑定值为2oldValue:指令绑定的前一个值,仅在updatecomponentUpdated钩子中可用。无论值是否改变都可用。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 编译生成的虚拟节点。移步VNode API来了解更多详情。oldVnode:上一个虚拟节点,仅在updatecomponentUpdated钩子中可用。

除了el之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的dataset来进行。

demo:自定义一个点击变色的指令v-my-color:

引入vue文件:

<script src="/npm/vue@2.6.14/dist/vue.js"></script>

html:

<template><div style="height: 50px;border: 1px solid #222;" v-my-color="targetColor"></div></template>

js:

写法一:new Vue() 实例前自定义

Vue.directive('my-color', {bind: function (el, binding) {el.addEventListener('click', function () {console.log(binding.value)el.style.backgroundColor = binding.value})}})new Vue({el: '#app',data: {targetColor: '#f66'}})

写法二:new Vue() 实例中自定义

new Vue({el: '#app',data: {targetColor: '#f66'},directives: {'my-color': {bind: function (el, binding) {el.addEventListener('click', function () {el.style.backgroundColor = binding.value})}}}})

一键复制功能 demo:

import { Message } from 'ant-design-vue';const vCopy = {bind(el, { value }) {el.$value = value; // 用一个全局属性来存传进来的值,因为这个值在别的钩子函数里还会用到el.handler = () => {if (!el.$value) {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);};// 绑定点击事件,一键复制el.addEventListener('click', el.handler);},componentUpdated(el, { value }) {el.$value = value;},unbind(el) {el.removeEventListener('click', el.handler);},};export default vCopy;

将自定义指令注册到全局:再新建一个 js ( directives.js )文件来注册所有的全局指令。

import copy from './v-copy';const directives = {copy,};export default {install(Vue) {Object.keys(directives).forEach((key) => {Vue.directive(key, directives[key]);});},};

在 main.js 中引入:

import Vue from 'vue';import Directives from './directives';Vue.use(Directives);

input 输入框 demo:

<template><input type="text" v-model="text" placeholder="仅可填入正整数数字"v-my-text="{key:'text',maxval:'1000'}"></template><script>export default {data(){return {text:'',}},directives:{myText:{bind(el,binding,vnode) {el.handler = function() {el.value = el.value.replace(/\D+/g, '')//根据设置的规则,进行判断处理if(binding.value.maxval && el.value > parseInt(binding.value.maxval)){el.value = parseInt(binding.value.maxval);}//根据指令调取位置设置的规则Key,进行全局上文赋值vnode['context'][binding.value.key] = el.value;}el.addEventListener('input', el.handler)},},}}</script>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。