vue指令用法

vue指令(directive)一般用于直接对DOM元素进行操作。

vue中已经提供的指令有很多:v-text, v-html, v-bind, v-on, v-model, v-if, v-show 等等

1. 指令的定义形式

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

2. 指令的钩子函数,总共有5个

bind:             首次绑定执行一次,负责初始化
inserted:          被绑定元素插入父节点时候调用,仅保证父节点存在,不一定已被插入文档
update:            组件VNode更新时,可能在其子VNode更新前
componentUpdated:  组件VNode及其子VNode都更新后调用
unbind:            解绑时调用

3. 指令的参数

el:       绑定的元素
binding:   绑定对象,包含参数值,value和oldValue
vnode:     当前虚拟节点
oldVnode:  上一个虚拟节点,仅在update和componentUpdate钩子可用

4. vue自定义指令的应用场景

4.1 v-copy 指令复制元素里面的内容

//基本原理是,在bind初始化后,给元素绑定一个click事件
//在click事件中,插入一个不显示的textarea,选中该textarea
//使用execCommand执行copy命令,复制textarea内容到剪贴板
//移除该textarea
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;

import copy from './v-copy';
// 自定义指令
const directives = {
  copy,
};
// 这种写法可以批量注册指令
export default {
  install(Vue) {
    Object.keys(directives).forEach((key) => {
      Vue.directive(key, directives[key]);
    });
  },
};

import Vue from 'vue';
import Directives from './directives';

Vue.use(Directives);

4.2 v-auth 控制按钮的可见性

基本原理,在inserted钩子函数中,判断是否有权限,无权限,则移除该按钮dom节点

export default {
  inserted(el, binding, vnode) {
    const { value } = binding
    const roles = store.getters && store.getters.roles

    if (Array.isArray(value) && value.length > 0) {
      const permissionRoles = value

      const hasPermission = roles.some(role => {
        return permissionRoles.includes(role)
      })

      //无权限就移除该node
      if (!hasPermission) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    }
  }
}

参考:https://www.cnblogs.com/chenwenhao/p/11924161.html

原文地址:https://www.cnblogs.com/mengff/p/12885976.html