1. 程式人生 > >vue使用clipboard外掛點選複製內容出錯/複製出錯問題

vue使用clipboard外掛點選複製內容出錯/複製出錯問題

專案使用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"));
  },