vue使用clipboard插件点击复制内容出错/复制出错问题
项目使用vue框架,iview的UI框架。在使用echarts做一个大屏的界面时,添加了点击对很长的网元名称进行复制的需求。
参考了网上对于clipboard插件的引用。这里是他的github地址:https://github.com/zenorocha/clipboard.js
1. 引入clipboard.js 2.在需要使用的组件中import 3. 添加需要复制的内容 4.添加方法
npm install clipboard --save
import Clipboard from 'clipboard';
<button class="tag-read" data-clipboard-text="我是可以复制的内容,啦啦啦啦" @click="copy">立即阅读</button>
copy() {
var clipboard = new Clipboard('.tag-read')
clipboard.on('success', e => {
console.log('复制成功')
// 释放内存
clipboard.destroy()
})
clipboard.on('error', e => {
// 不支持复制
console.log('该浏览器不支持自动复制')
// 释放内存
clipboard.destroy()
})
}
如果动态获取想要的内容
<input type="text" v-model="copyContent" id="copy_text" style="opacity: 0">
<button ref="copy" data-clipboard-action="copy" data-clipboard-target="#copy_text" @click="copy">复制</button>
this.copyBtn = new this.$clipboard(this.$refs.copy);
copy () {
let _this = this
let clipboard = _this.copyBtn
clipboard.on('success', function () {
Toast('复制成功')
})
clipboard.on('error', function () {
Toast('复制失败,请手动复制')
})
}
因为项目中使用了echarts,真实的dom很难获取。所以自己写了一个看不见的<p>标签。用来给clipboard实例化。
let that = this;
function extension(mychart) {
var yaxisTip = document.getElementById("yaxis-tip"); //判断是否创建过div框,如果创建过就不再创建了
mychart.on("mouseover", function(params) {
if (params.componentType == "yAxis") {
let tipH = params.event.offsetY + 700;
yaxisTip.setAttribute(
"style",
"display:inline-block;position:absolute;padding:5px;color:#fff;font-size:12px;left:75px;z-index:1000;background:#13294B;opacity:0.8;border-radius:3px;"
);
yaxisTip.style.top = tipH + "px";
yaxisTip.innerHTML = params.value+'- -点击此网元名称进行复制';
}
});
mychart.on("mouseout", function(params) {
if (params.componentType == "yAxis") {
yaxisTip.setAttribute("style", "display:none");
}
});
mychart.on("click", params => {
if (params.componentType == "yAxis") {
that.createanewnode1 = params.value;
let temp = document.getElementById("areateanewnode");
temp.dispatchEvent(new Event("click")); //触发复制方法
}
});
}
// 复制方法
copyPClickHandler(e) {
let temp1 = document.getElementById("areateanewnode");
let clipboard = new Clipboard(temp1);
clipboard.on("success", e => {
clipboard.destroy(); //使用destroy可以清楚缓存
});
clipboard.on("error", e => {
alert("内容复制失败");
clipboard.destroy();
});
},
使用let clipboard = new Clipboard(temp1);直接绑定id的话,不成功,如果是需要绑定的dom元素中绑定了这个复制事件,才能成功。所以想出了在触发click事件后用js中.dispatchEvent(new Event("click"));触发复制事件。
能够复制了之后出现了复制错误的问题,点击第一下不能复制成功,第二下正常复制。第三次点击不同的值复制的还是第二次的值,第四次点击之后复制第三次点击的值。
双击就能复制成功。
出现这个问题的原因是 that.createanewnode1 = params.value; 这句话给双向数据绑定的<p>标签赋值,从而获取到这个值。
而vue框架是在所有代码执行完毕后,才对dom进行更改。
解决方法:使用 Vue.nextTick(callback)
这样回调函数在 DOM 更新完成后就会调用。
mychart.on("click", params => {
if (params.componentType == "yAxis") {
that.createanewnode1 = params.value;
that.$nextTick(() => { //使用nextTick为了保证dom元素都已经渲染完毕
let temp = document.getElementById("areateanewnode");
temp.dispatchEvent(new Event("click"));
});
这样,第一次点击后获取不到,剩下的就可以单击复制了。可以往声明周期钩子里提前给他派发事件。就可以解决这个问题了
mounted() {
// 初始加载时,drillDown默认为false
this.refreshData();
let temp = document.getElementById("areateanewnode"); //加载界面首先获取一遍需要复制元素的dom
temp.dispatchEvent(new Event("click"));
},