vue3+ts 自定义指令v-copy实现复制文字

331 阅读1分钟

新建copy.ts文件,实现代码如下:

/**
 * v-copy
 * 复制某个值至剪贴板
 * 接收参数:string类型/Ref<string>类型/Reactive<string>类型
 */
import type { Directive, DirectiveBinding } from 'vue';
import { ElMessage } from 'element-plus';
interface ElType extends HTMLElement {
  copyData: string | number;
  __handleClick__: any;
}

const copy: Directive = {
  mounted(el: ElType, { value }: DirectiveBinding) {
    el.copyData = value;
    el.addEventListener('click', () => handleClick(el));
  },
  updated(el: ElType, { value }: DirectiveBinding) {
    el.copyData = value;
  },
  beforeUnmount(el: ElType) {
    el.removeEventListener('click', el.__handleClick__);
  },
};

function handleClick(el: ElType) {
  const value = (el.copyData ?? el.innerHTML) as string;
  navigator.clipboard.writeText(value).then(() => {
    ElMessage({
      type: 'success',
      message: `复制成功!`,
    });
  });
}
// 旧版写法
// function handleClick(el: ElType) {
//   const textarea = document.createElement('textarea');
//   textarea.readOnly = true;
//   textarea.style.position = 'absolute';
//   textarea.style.left = '-9999px';
//   /**
//    * 将要copy的值赋给textarea的value属性
//    */
//   textarea.value = (el.copyData ?? el.innerHTML) as string;
//   /**
//    * 将textarea 插入到body中
//    */
//   document.body.appendChild(textarea);
//   /**
//    * 实现选中并复制
//    * 利用select选中,
//    * 利用execCommand命令copy选中的内容到剪贴板中
//    */
//   textarea.select();
//   textarea.setSelectionRange(0, textarea.value.length);
//   const result = document.execCommand('Copy');
//   if (result) {
//     ElMessage({
//       type: 'success',
//       message: `${textarea.value} 复制成功!`,
//     });
//   }
//   /**
//    * 移出textarea
//    */
//   document.body.removeChild(textarea);
// }

export default copy;


使用方法:在main.js中引用并注册自定义指令

import copy from './common/copy';

app.directive('copy', copy);

组件中使用:在组件中直接使用

1、直接使用:默认复制当前标签内的内容

<span v-copy>复制内容</span>

2、在v-copy中传入参数,则复制的是传入的内容

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