1.使用document.execCommand(弃用)
import { Message } from 'ant-design-vue';
const vCopy = { //
/*
bind 钩子函数,第一次绑定时调用,可以在这里做初始化设置
el: 作用的 dom 对象
value: 传给指令的值,也就是我们要 copy 的值
*/
bind(el, { value }) {
el.$value = value; // 用一个全局属性来存传进来的值,因为这个值在别的钩子函数里还会用到
el.handler = () => {
if (!el.$value) {
// 值为空的时候,给出提示,我这里的提示是用的 ant-design-vue 的提示,你们随意
Message.warning('无复制内容');
return;
}
// 动态创建 textarea 标签
const textarea = document.createElement('textarea');
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly';
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
// 将要 copy 的值赋给 textarea 标签的 value 属性
textarea.value = el.$value;
// 将 textarea 插入到 body 中
document.body.appendChild(textarea);
// 选中值并复制
textarea.select();
// textarea.setSelectionRange(0, textarea.value.length);
const result = document.execCommand('copy');
if (result) {
Message.success('复制成功');
}
document.body.removeChild(textarea);
};
// 绑定点击事件,就是所谓的一键 copy 啦
el.addEventListener('click', el.handler);
},
// 当传进来的值更新的时候触发
componentUpdated(el, { value }) {
el.$value = value;
},
// 指令与元素解绑的时候,移除事件绑定
unbind(el) {
el.removeEventListener('click', el.handler);
},
};
export default vCopy;
<template>
<div>
<input v-model="text" placeholder="输入要复制的内容" />
<button v-copy="text">点击复制</button>
</div>
</template>
<script>
import vCopy from './directives';
export default {
data () {
return {
text: '这是要复制的内容' // 默认的复制内容
};
},
directives: {
copy: vCopy
}
};
</script>
- 自定义指令 v-copy 绑定到按钮上,点击按钮时会复制绑定的内容。
- el.$value 保存了要复制的内容,在每次点击时通过 document.execCommand(‘copy’) 复制到剪贴板。
- 当输入框内容变化时,componentUpdated 钩子会更新复制的内容。
execCommand
是一种用于执行与用户操作相关的命令的方法,主要用于在文档上执行剪贴板操作(如复制、剪切、粘贴)或格式化操作(如加粗、斜体、下划线)。还可以使用:“copy”、“cut”、“paste”、“bold”、“italic”
textarea
标签:
- 支持选中和复制操作:textarea 标签的内容可以被浏览器原生地选中,并且它能够被复制到剪贴板。复制操作依赖于选中文本,而 textarea 和 input 元素是 HTML 中可以轻松选中文本内容的表单元素。虽然 input 标签也可以用于复制文本,但相比于 textarea,input 标签有一些局限性,特别是在处理较长文本或多行文本时。
- textarea 标签支持 readonly 属性,可以确保它的内容在被复制之前不会被修改。将 textarea 设置为 readonly 能避免在移动设备上点击时唤起虚拟键盘,避免不必要的用户干扰。
2.Clipboard API
Clipboard API 是一个现代的 Web API,用于在网页上执行剪贴板操作(如复制和粘贴)。与 document.execCommand 不同,Clipboard API 提供了更现代的异步接口,并且支持在 HTTPS 页面上执行这些操作以确保安全性。
Clipboard API 的方法返回一个 Promise,这意味着你可以使用 then 和 catch 方法来处理成功和失败的情况。
实现一键粘贴的功能:
使用 navigator.clipboard.readText() 方法从剪贴板读取文本:
let vCopy = {
bind (el, { value }) {
el.$value = value;
el.handler = async () => {
if (!el.$value) {
console.log('没有要复制的内容');
return;
}
try {
// 直接使用 Clipboard API 复制
await navigator.clipboard.writeText(el.$value);
console.log('复制成功');
} catch (err) {
console.error('复制失败', err);
}
};
// 监听点击事件
el.addEventListener('click', el.handler);
},
componentUpdated (el, { value }) {
el.$value = value;
},
unbind (el) {
el.removeEventListener('click', el.handler);
}
};
export default vCopy;
<template>
<div>
<input v-model="text" placeholder="输入要复制的内容" />
<button v-copy="text">点击复制</button>
</div>
</template>
<script>
import vCopy from './directives';
export default {
data () {
return {
text: '这是要复制的内容' // 默认的复制内容
};
},
directives: {
copy: vCopy
}
};
</script>
navigator 是 window 对象的一个属性,提供了有关用户浏览器的信息和一些特定的功能。
主要功能:
- 提供有关用户代理(浏览器)和操作系统的信息。
- 提供浏览器的语言设置和在线状态等信息。
- 提供对剪贴板操作、地理位置、媒体设备等现代浏览器功能的访问。
拓展:
使用 navigator.clipboard.writeText() 方法将文本写入剪贴板:
<template>
<div>
<input v-model="text" placeholder="输入要复制的内容" />
<button @click="copyToClipboard">点击复制</button>
</div>
</template>
<script>
export default {
data() {
return {
text: '默认要复制的内容'
};
},
methods: {
copyToClipboard() {
navigator.clipboard.writeText(this.text).then(() => {
console.log('文本已成功复制到剪贴板');
}).catch(err => {
console.error('复制失败', err);
});
}
}
};
</script>