vue 自定义指令之v-copy

553 阅读1分钟

功能实现

  • 当用户点击时, 将文本框中的内容传给函数, 函数实现复制功能

实现思路

  • 使用vue的自定义指令实现其功能
  • 当页面初始化时, 先注册该功能函数,等待用户点击后触发

v-copy.js


import { Message } from 'element-ui'
const vCopy = {
  /*
  bind 钩子函数,第一次绑定时调用,可以在这里做初始化设置
  el: 作用的 dom 对象
  value: 传给指令的值,也就是我们要 copy 的值
  */
  bind(el, {
    value
  }) {
    el.$value = value; // 用一个全局属性来存传进来的值,因为这个值在别的钩子函数里还会用到
    el.handler = () => {
      if (!el.$value) {
        Message({
          message: '无复制内容',
          type: '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);
      // document.execCommand使用该命令来操纵可编辑内容区域的元素
      const result = document.execCommand('Copy');
      if (result) {
        Message({
          message: '复制成功',
          type: '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;

/**
bind: 只调用一次, 指令第一次绑定到元素时调用
*/

注册指令

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