项目使用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"));
  },

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐