Copy url to clipboard via button click in a vuejs component

32,696

Solution 1

If you need to use vuejs ref add it as attribute

<a :href="link_url" class="text-dark" target="_blank" rel="noopener noreferrer" ref="mylink">
    {{ link_name }}
</a>

and use it in your method in the following way:

  methods: {
    copyURL() {
      var Url = this.$refs.mylink;
      Url.innerHTML = window.location.href;
      console.log(Url.innerHTML)
      Url.select();
      document.execCommand("copy");
    }
  }

However, you should take a look to this link for a better cross-browsing solution. In this case you don't need the ref attribute.

This is the solution in the link adapted to your case:

methods: {
    copyUrl() {
        const el = document.createElement('textarea');  
        el.value = this.link_url;                                 
        el.setAttribute('readonly', '');                
        el.style.position = 'absolute';                     
        el.style.left = '-9999px';                      
        document.body.appendChild(el);                  
        const selected =  document.getSelection().rangeCount > 0  ? document.getSelection().getRangeAt(0) : false;                                    
        el.select();                                    
        document.execCommand('copy');                   
        document.body.removeChild(el);                  
        if (selected) {                                 
          document.getSelection().removeAllRanges();    
          document.getSelection().addRange(selected);   
        }
    }
}

Solution 2

You can use navigator object with clipboard in javascript.

Note: navigator.clipboard.writeText is asynchronous.

methods: {
  async copyURL(mytext) {
    try {
      await navigator.clipboard.writeText(mytext);
      alert('Copied');
    } catch($e) {
      alert('Cannot copy');
    }
  }
}

Solution 3

Most modern web explorers (2021) let you use this: navigator.clipboard.writeText("yourText");

Just in case you can also do this:

  const clipboardData =
    event.clipboardData ||
    window.clipboardData ||
    event.originalEvent?.clipboardData ||
    navigator.clipboard;

  clipboardData.writeText(message);

Solution 4

does not work for me, try this -

<input type="hidden" id="testing-code" :value="testingCode">

copyTestingCode () {
      let testingCodeToCopy = document.querySelector('#testing-code')
      testingCodeToCopy.setAttribute('type', 'text') 
      testingCodeToCopy.select()

      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Testing code was copied ' + msg);
      } catch (err) {
        alert('Oops, unable to copy');
      }

      /* unselect the range */
      testingCodeToCopy.setAttribute('type', 'hidden')
      window.getSelection().removeAllRanges()
    },

https://codepen.io/PJCHENder/pen/jamJpj?editors=1010, please

Share:
32,696
mahatmanich
Author by

mahatmanich

Updated on July 05, 2022

Comments

  • mahatmanich
    mahatmanich almost 2 years

    I have following component, and I would like to have a button that copies the link_url to the clipboard on click.

    I have javascript code that works when selecting an id, however the links do not have an id. Can I accomplish the selection of the a-tag via refs in the component itself, or what would be the best way to get this done.

    I was also thinking about generating an a-tag with the this.link_url in the copyURL() dynamically but I guess that would be very dirty.. I am looking for the vuejs way.

    <template>
      <li class="list-group-item">
        <a :href="link_url" 
             class="text-dark" 
             target="_blank" 
             rel="noopener noreferrer">{{ link_name }}</a>
        <button @click="copyUrl">copy url from a tag</button>
      </li>      
    </template>
    
    <script>
    export default {
      props: ["link_url", "link_name"],
      methods: {
        copyURL() {
          var Url = document.getElementById('myid'); /*GET vuejs el reference here (via $ref) but how?*/
          Url.innerHTML = window.location.href;
          console.log(Url.innerHTML)
          Url.select();
          document.execCommand("copy");
        }
      }
    }
    </script>
    
    <style>
    </style>
    
  • mahatmanich
    mahatmanich over 4 years
    Thanks for the answer @fabruex. I have many links on a page, would $ref refer only to the link within the component or is the scope of $refs global, thus referring to all links then? Would I need a unique ref for each link component?
  • Fab
    Fab over 4 years
    If you have multiple ref="foo" within the same component $refs.foo will refer to the last one in the DOM. If you a have ref="foo" in an element with the v-for attribute $refs.foo will be an array. Check this: blog.logrocket.com/…
  • mahatmanich
    mahatmanich over 4 years
    So this is not a viable vuejs solution. However, I like the other proposed solution you posted!
  • Fab
    Fab over 4 years
    Yes, you can add the url to copy as method parameter and for every link something like this in the template: <a :href="urlstring">{{ link_name }}</a><button @click="copyUrl(urlstring)">Copy URL</button>
  • Jeremy Hamm
    Jeremy Hamm over 2 years
    Just a heads up, this will not work on a non HTTPS connection