vue使用clipboard外掛點選複製內容出錯/複製出錯問題
阿新 • • 發佈:2019-02-15
專案使用vue框架,iview的UI框架。在使用echarts做一個大屏的介面時,添加了點選對很長的網元名稱進行復制的需求。
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"));
},