Vue自定义复制指令 v-copy功能的实现

使用自定义指令创建一个点击复制文本功能

1. 创建v-copy.js文件

import Vue from \"vue\";
// 注册一个全局自定义复制指令 `v-copy`
Vue.directive(\"copy\", {
  bind(el, { value }) {
    el.$value = value;
    el.handler = () => {
      el.style.position = \'relative\';
      if (!el.$value) {
        // 值为空的时候,给出提示
        alert(\'无复制内容\');
        return
      }
      // 动态创建 textarea 标签
      const textarea = document.createElement(\'textarea\');
      // 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
      textarea.readOnly = \'readonly\';
      textarea.style.position = \'absolute\';
      textarea.style.top = \'0px\';
      textarea.style.left = \'-9999px\';
      textarea.style.zIndex = \'-9999\';
      // 将要 copy 的值赋给 textarea 标签的 value 属性
      textarea.value = el.$value
      // 将 textarea 插入到 el 中
      el.appendChild(textarea);
      // 兼容IOS 没有 select() 方法
      if (textarea.createTextRange) {
        textarea.select(); // 选中值并复制
      } else {
        textarea.setSelectionRange(0, el.$value.length);
        textarea.focus();
      }
      const result = document.execCommand(\'Copy\');
      if (result) alert(\'复制成功\');
      el.removeChild(textarea);
    }
    el.addEventListener(\'click\', el.handler); // 绑定点击事件
  },
  // 当传进来的值更新的时候触发
  componentUpdated(el, { value }) {
    el.$value = value;
  },
  // 指令与元素解绑的时候,移除事件绑定
  unbind(el) {
    el.removeEventListener(\'click\', el.handler);
  },
});

2. 引入v-copy

//  main.js 根据文件的相关路径引入v-copy.js文件
import \"xx/v-copy.js\"; // v-copy 指令

3. 在标签使用v-copy

<span v-copy=\"复制内容\">复制</span>

补充:Vue 自定义指令合集 (文本内容复制指令 v-copy)

我们常常在引入全局功能时,主要都是写于 js 文件、组件中。不同于他们在使用时每次需要引用或注册,在使用上指令更加简洁。

今天主要实现的是一个复制文本指令*v-copy*,其中主要的参数有两个icondblclick

参数 说明
dblclick 双击复制
icon 添加icon复制按钮,单击按钮实现复制

代码如下:

bind(el, binding) {
    if (binding.modifiers.dblclick) {
        el.addEventListener(\"dblclick\", () => handleClick(el.innerText));
        el.style.cursor = \"copy\";
    } else if (binding.modifiers.icon) {
        el.addEventListener(\"mouseover\", () => {
            if (el.hasicon) return;
            const icon = document.createElement(\"em\");
            icon.setAttribute(\"class\", \"demo\");
            icon.setAttribute(\"style\", \"{margin-left:5px,color:red}\");
            icon.innerText = \"复制\";
            el.appendChild(icon);
            el.hasicon = true;
            icon.addEventListener(\"click\", () => handleClick(el.innerText));
            icon.style.cursor = \"pointer\";
        });
        el.addEventListener(\"mouseleave\", () => {
            let em = el.querySelector(\"em\");
            el.hasicon = false;
            el.removeChild(em);
        });
    } else {
        el.addEventListener(\"click\", () => handleClick(el.innerText));
        el.style.cursor = \"copy\";
    }
    function handleClick(content) {
        if (Window.clipboardData) {
            window.Clipboard.setData(\"text\", content);
            return;
        } else {
            (function(content) {
                document.oncopy = function(e) {
                    e.clipboardData.setData(\"text\", content);
                    e.preventDefault();
                    document.oncopy = null;
                };
            })(content);
            document.execCommand(\"Copy\");
        }
    }
},
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容