vue点击按钮复制 或 ctrl + c 或选中需要复制的文本并处理文本样式进行复制

2,025 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

【复制功能】在项目中是比较常见的,eg: 点击按钮复制银行卡号,选择人员信息复制添加到excel表格等; 但是执行 ctrl + c 命令,这样会把文本的样式也一同复制,有时候并不符合用户的需求,下面介绍几种复制的方法:

一、 通过构建input实列的方法

<template>
  <div id="app">
      <div ref="copy-content">{{ encryptionCardNo }}</div>
      <button @click="handleCopy">复制</button>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      cardNo: '123456789'
    }
  },
  computed: {
    encryptionCardNo() {
      return this.cardNo.slice(0,3)+'****'+this.cardNo.slice(-2)
    }
  },
  methods:{
    handleCopy() {
      let input = document.createElement('input'); // 构建临时input
      input.value = this.cardNo;  // 要复制的内容
      document.body.appendChild(input);  // 添加临时实例
      input.select(); // 选择实例内容
      document.execCommand('copy') // 选择实例内容
      document.body.removeChild(input); // 删除临时实例
    },
  }
}
</script>

控制台就是复制的文本内容 image.png

二、 引入clipboard.js

  1. 使用 npm 安装:npm install clipboard --save 或
    yarn add clipboard -S
    安装后 package.jason就会出现对应的版本 image.png

或者直接引入 js 脚本:<script src="js/clipboard.min.js"></script>
(下载地址:clipboardjs.com/

  1. 导入
mian.js中全局引入
import Clipboard from 'clipboard'Vue.prototype.Clipboard=Clipboard;
在单个vue中引入
单页面引用:import Clipboard from "clipboard";
  1. 实现
<template>
  <div id="app">
      <div class="copy-content">{{ encryptionCardNo }}</div>
      <button class="copy-btn"  @click="handleCopy">复制</button>
  </div>
</template>

<script>
import Clipboard from 'clipboard'
export default {
  name: 'App',
  data() {
    return {
      cardNo: '123456789'
    }
  },
  computed: {
    encryptionCardNo() {
      return this.cardNo.slice(0,3)+'****'+this.cardNo.slice(-2)
    }
  },
  methods:{
    handleCopy() {
      const clipboard = new Clipboard(".copy-btn",{
        // 1. 通过target指定要复印的节点
        // target: function() {
        //   return document.querySelector('.copy-content');
        // }

        // 2. 点击copy按钮,直接通过text直接返回复印的内容
        text: ()=> {
          return this.cardNo;
        }
      });
      clipboard.on("success", (e) => {
        console.log(e)
        alert('复制成功')
        // 释放内存
        clipboard.destroy();
      });
      clipboard.on("error", (e) => {
        // 不支持复制
        alert('该浏览器不支持自动复制');
        // 释放内存
        clipboard.destroy();
      });
    },
  }
}
</script>
  1. 结果 使用 target 属性: 的返回的是选中 dom 元素的内容 image.png

使用 text 属性,直接返回复印的内容 image.png

三、 去掉空格,换行等样式

<template>
  <div id="app">
      <div @copy="handleCopy" class="copy-content">
        <span class="name">{{ '张三' }}</span>
        <span class="age">{{ '18岁' }}</span>
        <span class="mobile">{{ '1234567890' }}</span>
      </div>
  </div>
</template>

<script>
export default {
  name: 'App',
  methods:{
    handleCopy(event) {
      event.preventDefault();
      const valueStr = (window.getSelection().toString()).replace(/[\u00A0\n]/gi, ' ').replace(/^\s+/,'');
      if (event.clipboardData) {
        event.clipboardData.setData('text/plain', valueStr);
      } else {
        if (window.clipboardData) {
          return window.clipboardData.setData('text', valueStr);
        }
        let input = document.createElement('input'); // 构建临时
        input.value = valueStr;  // 要复制的内容 
        document.body.appendChild(input); // 添加临时实例 
        input.select(); // 选择实例内容 
        document.execCommand('copy') // 选择实例内容 
        document.body.removeChild(input); // 删除临时实例
      }
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.copy-content {
  position: relative;
  display: inline-flex;
  width: 100%;
  height: 20px;
  overflow: hidden;
  font-size: 14px;
  line-height: 20px;
  white-space: nowrap;
}
.name {
  width: auto;
  max-width: 100px;
  margin-right: 12px;
  overflow: hidden;
  font-weight: bold;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.age,
.mobile {
  margin-right: 12px;
}
</style>

结果:

  1. 未处理 image.png
  2. 处理后

image.png