v-copyText 自定义指令 —— 复制文本内容

v-copyText 自定义指令 ------ 复制文本内容

简介

v-copyText 是一个用于 Vue.js 项目的自定义指令,它允许用户点击元素后自动复制文本内容到剪贴板,并支持回调函数处理复制成功后的逻辑。


代码实现

ini 复制代码
/**
 * v-copyText 自定义指令 - 复制文本内容到剪贴板
 * Copyright (c) 2022 ruoyi
 */

export default {
  beforeMount(el, { value, arg }) {
    // 如果指令的参数是 "callback",则将回调函数存储在元素上
    if (arg === "callback") {
      el.$copyCallback = value;
    } else {
      // 否则,将复制的内容存储在元素上
      el.$copyValue = value;

      // 定义点击事件处理函数
      const handler = () => {
        // 调用复制文本到剪贴板的函数
        copyTextToClipboard(el.$copyValue);

        // 如果存在回调函数,则执行回调
        if (el.$copyCallback) {
          el.$copyCallback(el.$copyValue);
        }
      };

      // 监听点击事件,点击时触发复制操作
      el.addEventListener("click", handler);

      // 存储销毁函数,用于移除事件监听
      el.$destroyCopy = () => el.removeEventListener("click", handler);
    }
  }
}

/**
 * 复制文本到剪贴板
 * @param {string} input - 要复制的文本内容
 * @param {Object} options - 额外选项,可指定目标元素
 */
function copyTextToClipboard(input, { target = document.body } = {}) {
  // 创建一个 textarea 元素用于复制
  const element = document.createElement('textarea');

  // 记录当前焦点的元素
  const previouslyFocusedElement = document.activeElement;

  // 设置 textarea 的值为需要复制的文本
  element.value = input;

  // 使文本框只读,防止移动端弹出键盘
  element.setAttribute('readonly', '');

  // 设置样式,确保不会影响页面布局
  element.style.contain = 'strict';
  element.style.position = 'absolute';
  element.style.left = '-9999px';
  element.style.fontSize = '12pt'; // 防止 iOS 上的自动缩放

  // 记录当前选区
  const selection = document.getSelection();
  const originalRange = selection.rangeCount > 0 && selection.getRangeAt(0);

  // 将 textarea 添加到页面
  target.append(element);

  // 选中文本
  element.select();

  // 解决 iOS 兼容性问题,手动设置选择范围
  element.selectionStart = 0;
  element.selectionEnd = input.length;

  let isSuccess = false;
  try {
    // 执行复制命令
    isSuccess = document.execCommand('copy');
  } catch { }

  // 复制完成后移除 textarea 元素
  element.remove();

  // 恢复之前的选区
  if (originalRange) {
    selection.removeAllRanges();
    selection.addRange(originalRange);
  }

  // 将焦点恢复到之前的元素
  if (previouslyFocusedElement) {
    previouslyFocusedElement.focus();
  }

  return isSuccess;
}

代码解析

1. 自定义指令 v-copyText

  • 该指令用于在元素上绑定点击复制功能。
  • beforeMount 钩子在指令绑定到元素之前触发。
  • 如果 arg === "callback",则将回调函数存储到 el.$copyCallback,以便在复制完成后调用。
  • 否则,将要复制的文本存储在 el.$copyValue,并绑定 click 事件执行复制逻辑。

2. copyTextToClipboard 函数

  • 创建 textarea 元素,写入需要复制的文本。
  • 通过 document.execCommand('copy') 执行复制操作。
  • 移除 textarea 并恢复用户之前的选区和焦点。

使用方式

1. 在 Vue 组件中使用

xml 复制代码
<template>
  <button v-copyText="'要复制的文本'">点击复制</button>
</template>

2. 使用回调函数

xml 复制代码
<template>
  <button v-copyText:callback="copySuccess">点击复制</button>
</template>

<script>
export default {
  methods: {
    copySuccess(text) {
      console.log(`复制成功: ${text}`);
    }
  }
}
</script>

结论

v-copyText 是一个简单而实用的 Vue 自定义指令,可以轻松实现点击复制文本的功能,并且支持回调函数处理复制成功后的逻辑,非常适用于需要复制文本内容的场景,比如分享链接、邀请码、文本复制等功能。

相关推荐
sbjdhjd5 小时前
Redis 主从复制、哨兵高可用与 Cluster 集群部署实验手册
运维·前端·redis·云原生·开源·bootstrap·html
乐兮创想 小林5 小时前
企业官网移动端性能优化实战:从 Core Web Vitals 到图片/CDN/响应式的工程清单
前端·性能优化·网站建设·北京网站建设公司
前端一小卒6 小时前
不手写代码的第 30 天,我才明白前端这个岗位还剩什么
前端·javascript·ai编程
Ajie'Blog6 小时前
Copilot Agent Tasks API 开放:AI 编程开始进入后台任务时代
服务器·前端·javascript·人工智能·copilot·ai编程
老毛肚6 小时前
jeecgboot vue TS & 模板化 04
前端·javascript·vue.js
AI_零食8 小时前
鸿蒙PC Electron跨平台应用开发:24时区时间表应用详解
前端·华为·electron·开源·harmonyos·鸿蒙
Electrolux8 小时前
[onlyoffice-v9]纯前端怎么实现编辑预览office
前端·javascript·github
码云之上8 小时前
聊聊如何设计一个高效、稳定的 Node.js 接入层
前端·后端·node.js
kyriewen9 小时前
我读了一遍 Babel 编译后的 async/await,终于搞懂了它的原理(附 20 行手写实现)
前端·javascript·面试
IT_陈寒9 小时前
Vite项目build后路由404了?你可能漏了这个小配置
前端·人工智能·后端