Bootstrap

vue实现点击复制功能

点击复制功能

1.通过使用浏览器的Clipboard API

使用navigator.clipboard.writeText()。如果用户授予了相应的权限,就能提供系统剪贴板的读写访问。在 Web 应用程序中,Clipboard API 可用于实现剪切、复制和粘贴功能。Clipboard API方法是异步的,返回一个promise对象。

export default {
  data() {
    return {
      textToCopy: '要复制的文本'
    }
  },
  methods: {
    copyToClipboard() {
      navigator.clipboard.writeText(this.textToCopy).then(() => {
        console.log('复制成功');
      }).catch(err => {
        console.log('复制失败', err);
      });
    }
  }
}

navigator.clipboard.writeText 方法可能会在某些情况下失效,以下是一些可能的原因:

  1. 权限问题:在某些浏览器中,Clipboard API 可能需要用户的权限才能使用。如果没有得到用户的允许,navigator.clipboard.writeText 方法可能会失效。
  2. 浏览器兼容性:并非所有的浏览器都支持 Clipboard API。在不支持 Clipboard API 的浏览器中,navigator.clipboard.writeText 方法会失效。
  3. 在非用户交互的上下文中使用:出于安全考虑,大多数浏览器只允许在用户交互的上下文中(例如点击事件的处理函数)使用 Clipboard API。如果你在非用户交互的上下文中使用 navigator.clipboard.writeText 方法,它可能会失效。

如果你遇到 navigator.clipboard.writeText 方法失效的问题,你可以尝试以下以下的解决方案:

  1. 检查你的代码是否在用户交互的上下文中使用 navigator.clipboard.writeText 方法:如果不是,你需要将你的代码移动到一个用户交互的上下文中,例如一个点击事件的处理函数。
  2. 检查你的网站是否有使用 Clipboard API 的权限:你可以在浏览器的设置中查看和修改你的网站的权限。
  3. 使用一个兼容性更好的方法:如果你需要支持不支持 Clipboard API 的浏览器,你可以使用 document.execCommand('copy') 方法作为一个备选方案。但是请注意,这个方法在一些新的浏览器中可能已经被废弃。

2.使用document.execCommand('copy')方法

通过创建一个textarea元素,将要复制的文本设置成textarea的value,然后将其添加到文档中,选中文本使用document.execCommand('copy')方法进行复制,最后将textarea元素移除。

export default {
  data() {
    return {
      textToCopy: '要复制的文本'
    }
  },
  methods: {
    copyToClipboard() {
      // 创建一个textarea元素
      const textarea = document.createElement('textarea');
      // 设置textarea的值为要复制的文本
      textarea.value = this.textToCopy;
      // 将textarea添加到文档中
      document.body.appendChild(textarea);
      // 选中textarea中的文本
      textarea.select();
      try {
        // 尝试复制选中的文本
        const successful = document.execCommand('copy');
        const msg = successful ? '复制成功' : '复制失败';
        console.log(msg);
      } catch (err) {
        console.log('不能使用这种方法复制', err);
      }
      // 将textarea从文档中移除
      document.body.removeChild(textarea);
    }
  }
}
}

请注意,document.execCommand('copy')方法在一些新的浏览器中可能已经被废弃,因此这只应作为一个备选方案。

3.两种方法合并(ts版)

const copyToClipboard = (text: string) => {
  if (navigator.clipboard) {
    navigator.clipboard
      .writeText(text)
      .then(() => {
       message.success('复制成功')
      })
      .catch(() => {
        message.success('复制失败')
      })
  } else {
    // 创建一个textarea元素
    const textarea = document.createElement('textarea')
    // 设置textarea的值为要复制的文本
    textarea.value = text
    // 将textarea添加到文档中
    document.body.appendChild(textarea)
    // 选中textarea中的文本
    textarea.select()
    try {
      // 尝试复制选中的文本
      const successful = document.execCommand('copy')
      successful ? message.success('复制成功') : message.success('复制失败')
    } catch (err) {
      console.log('不能使用这种方法复制', err)
    }
    // 将textarea从文档中移除
    document.body.removeChild(textarea)
  }
}

4.使用自定义指令v-copy(vue2版)

import Vue from 'vue'
import { Message } from 'view-design'
// 注册一个全局自定义复制指令 `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) Message.success('复制成功')
      el.removeChild(textarea)
    }
    el.addEventListener('click', el.handler) // 绑定点击事件
  },
  // 当传进来的值更新的时候触发
  componentUpdated (el, { value }) {
    el.$value = value
  },
  // 指令与元素解绑的时候,移除事件绑定
  unbind (el) {
    el.removeEventListener('click', el.handler)
  }
})

然后在main.js引用

;