vue 复制文本、二维码到剪贴板

文章介绍了如何在Vue应用中安装vue-qr组件,以及在不同安全上下文中处理文本和二维码的复制功能,包括使用navigator.clipboardAPI和document.queryCommandSupported方法的兼容性策略。
摘要由CSDN通过智能技术生成

1、安装依赖:

npm install vue-qr

2、只复制文本:

<template>
  <div style="text-align:center;">
    <div ref="copybox">
      <div>百度一下,你就知道:</div>
      <div>https://www.baidu.com</div>
    </div>
    <el-button type="success" @click="copyContent" size="small" style="margin-top:20px;">复制文本</el-button>
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {
    // 复制
    copyContent() {
      if (navigator.clipboard && window.isSecureContext) {// navigator clipboard 需要 https 等安全上下文
        // 需要在安全网络下进行,localhost 或者 https 或者 127.0.0.1,可以获取到 clipboard,谷歌现在很多 api 都要求 https 的情况
        let copyText = "百度一下,你就知道:\nhttps://www.baidu.com";// 要复制的文本
        navigator.clipboard.writeText(copyText).then(() => {
          this.$message.success('文本已复制到剪贴板');
        }).catch(error => {
          this.$message.error('复制失败:' + error);
        })
      } else if (document.queryCommandSupported && document.queryCommandSupported('copy')) {// 检测是否支持 document.queryCommandSupported 和 copy 指令
        // 非安全域使用,较老旧的方法,可能废弃
        this.$nextTick(function () {// nextTick,当前 dom 渲染完毕的回调
          let range = document.createRange()// 创建 range
          range.selectNode(this.$refs.copybox)// //range 选中节点,图片要是 http 地址且长度不是很长
          let selection = window.getSelection()// 获取 selection 对象
          if (selection.rangeCount > 0) {
            // 如果有已经选中的区域,直接全部去除
            selection.removeAllRanges()
          }
          selection.addRange(range)// 加入到选区中
          document.execCommand('copy')// copy 是复制
          selection.removeAllRanges() // 去除选中区域,取消拖蓝效果
          this.$message.success("文本已复制到剪贴板");
        })
      } else {
        this.$message.error('抱歉,当前浏览器不支持此功能,请手动复制');
      }
    },
  },
};
</script>

<style scoped lang="stylus"></style>

3、复制文本和二维码:

<template>
  <div style="text-align:center;">
    <div ref="copybox">
      <div>百度一下,你就知道:</div>
      <div>https://www.baidu.com</div>
      <vue-qr class="qr" :text="linkUrl" :value="linkUrl" :size="90" :margin="0"></vue-qr>
    </div>
    <div style="margin-top:20px;">
      <el-button type="success" @click="copyContent" size="small">复制文本和二维码</el-button>
    </div>
  </div>
</template>

<script>
import VueQr from 'vue-qr';

export default {
  components: { VueQr },
  data() {
    return {
      linkUrl: "https://www.baidu.com/"
    };
  },
  methods: {
    // 图片元素转 base64
    getBase64Image(img) {
      let canvas = document.createElement('canvas');
      canvas.width = img.width;
      canvas.height = img.height;
      let ctx = canvas.getContext('2d');
      ctx?.drawImage(img, 0, 0, img.width, img.height);
      let dataURL = canvas.toDataURL('image/png');
      return dataURL;
    },
    // base64 图片转为 blob
    getBlobImage(dataurl) {
      let arr = dataurl.split(',');
      let mime = arr[0].match(/:(.*?);/)[1];
      let bstr = atob(arr[1]);
      let n = bstr.length;
      let u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },
    // 复制
    copyContent() {
      if (navigator.clipboard && window.isSecureContext) {// navigator clipboard 需要 https 等安全上下文
        // 需要在安全网络下进行,localhost 或者 https 或者 127.0.0.1,可以获取到 clipboard,谷歌现在很多 api 都要求 https 的情况
        let copyText = new Blob(["百度一下,你就知道:\nhttps://www.baidu.com\n"], { type: "text/plain" });// 要复制的文本
        let copyImg = document.getElementsByClassName('qr')[0];// 要复制的二维码
        let dataurl = this.getBase64Image(copyImg);
        let blob = this.getBlobImage(dataurl);
        const item = new ClipboardItem({
          'text/plain': copyText,
          'image/png': blob
        });
        // 写入剪贴板,成功会执行 resolve,失败则走 reject
        navigator.clipboard.write([item]).then(() => {
          this.$message.success("已复制到剪贴板");
        }, (err) => {
          this.$message.error("复制失败");
          console.log(err);
        });
      } else if (document.queryCommandSupported && document.queryCommandSupported('copy')) {// 检测是否支持 document.queryCommandSupported 和 copy 指令
        // 非安全域使用,较老旧的方法,可能废弃
        this.$nextTick(function () {// nextTick,当前 dom 渲染完毕的回调
          let range = document.createRange()// 创建 range
          range.selectNode(this.$refs.copybox)// //range 选中节点,图片要是 http 地址且长度不是很长
          let selection = window.getSelection()// 获取 selection 对象
          if (selection.rangeCount > 0) {
            // 如果有已经选中的区域,直接全部去除
            selection.removeAllRanges()
          }
          selection.addRange(range)// 加入到选区中
          document.execCommand('copy')// copy 是复制
          selection.removeAllRanges() // 去除选中区域,取消拖蓝效果
          this.$message.success("已复制到剪贴板");
        })
      } else {
        this.$message.error('抱歉,当前浏览器不支持此功能,请手动复制');
      }
    },
  },
};
</script>

<style scoped lang="stylus"></style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值