方式
- document.execCommand
- navigator.clipboard
- Clipboard.js
- vue2-clipboard
document.execCommand
使用方式
<textarea ref="copyInput" :value="copyInfo" />
this.$nextTick(() => { // 为防止dom未加载完,包裹在$nextTick里
const copyInput = this.$refs.copyInput
copyInput.select()
document.execCommand('copy')
this.$message.success('复制成功,可粘贴查看')
})
问题
document.execCommand不同浏览器以及浏览器的不同版本兼容性较差,甚至会出现使用时既不报错也没有效果的现象,而且现在已经允许浏览器自行砍掉这个api,不推荐使用。
navigator.clipbard
使用方式
navigator.clipboard.writeText(this.copyInfo).then(() => {
this.$message.success('复制成功,可粘贴查看')
}).catch(err => {
this.$message.err('复制失败,', JSON.stringify(err))
})
问题
navigator.clipboard浏览器兼容性较好,支持异步复制,但对安全性要求较高,仅支持本地使用和https的网站使用,http网站禁用
Clipboard.js
使用
npm或者yarn安装clipboard.js
npm i clipboard.js
<div id="LoadSql" :data-clipboard-text="copyInfo" @click.stop="copyInfo()">点我复制</div>
// 引入
import Clipboard from 'clipboard.js'
// data()中存储初始化复制按钮事件
copyBtn: null
// mounted()中注册
this.copyBtn = new Clipboard(#LoadSql)
// methods
copyInfo(){
const clipboard = new Clipboard('#LoadSql')
clipboard.on('success', e => {
this.$message.success('复制成功,可粘贴查看')
// 释放内存
clipboard.destroy()
})
clipboard.on('error', e => {
// 不支持复制
this.$message.warning('该浏览器不支持自动复制')
// 释放内存
clipboard.destroy()
})
}
问题
new Clipboard中传入的对象只能是原始Dom元素,传入封装的组建会报错。
旧版本的浏览器,比如chrome69等不支持异步使用。
第二次点击才能正常复制,相当于第n次点击复制的是(n-1)次点击的内容
vue-clipboard2
vue-clipboard2是基于clipboard.js的一个封装,并提供了多个自定义指令
使用
- 普通使用
this.$copyText(this.copyInfo).then(
function(e) {
alert('复制成功')
},
function(e) {
console.log(e)
alert('复制失败')
}
)
- 自定义指令
<div
v-clipboard:copy="copyInfo"
v-clipboard:success="onSuccess"
v-clipboard:error="onFailed"
@click.stop.prevent="copyInfo"
>
点我复制
</div>
问题
支持异步使用,但需手动触发按钮click事件,也有clipboard.js的n-1次的通病。
解决
搭配Clipboard.js,在dom元素上添加@mouseenter.once调用一遍函数与复制,相当于第1次,后续再使用点击调用时就正常了
<div
v-clipboard:copy="copyInfo"
v-clipboard:success="onSuccess"
v-clipboard:error="onFailed"
@mouseenter.once="copyInfo($event)"
@click.stop.prevent="copyInfo"
>
点我复制
</div>
async copyInfo(event) {
const params = {}
this.dataLoading = true
try {
const res = await getFun(params)
this.copyInfo = res.data.content
} catch (err) {
this.$message.err(err)
}
if (isMouseEnter) {
setTimeout(() => {
const clipbard = new Clipboard(event.target)
clipbard.on('success', e => {
// 释放内存
clipbard.destroy()
})
clipbard.on('error', e => {
// 释放内存
clipbard.destroy()
})
}, 500)
}
},
总结
-
同步复制
- document.execCommand (不推荐)
- navigator.clipboard (仅hhtps生效)
- clipboard.js
- vue-clipboard2
-
异步复制
- navigator.clipboard (仅hhtps生效)
- clipboard.js (低版本浏览器不生效,n-1次复制问题)
- vue-clipboard2 (低版本浏览器不生效,n-1次复制问题)
- vue-clipboard2自定义指令 + @mouseenter.once主动触发一次clipboard (解决问题)