Skip to content
Advertisement

How to run a function whenever unknown anchor tags are clicked in Vue.js 3?

I have a div with v-html that displays data from a database:

<div id="Content" v-html="${Content}"></div>

Within the ${Content} that is presented, there can be any number of a tags with links to other external pages. I need to parse these and then add an @click handler to each of them. An example would be:

<p>Calm down, Marty, I didn't disintegrate anything. The <a href="example.com/m">molecular structure</a> of Einstein and the car are completely intact. They wanted me to build them a bomb, so I took their <a href="example.com/d">plutonium</a> and in turn gave them a shiny bomb case full of used pinball machine parts.

To transform into this:

<p>Calm down, Marty, I didn't disintegrate anything. The <a @click="validateLink()" href="example.com/m">molecular structure</a> of Einstein and the car are completely intact. They wanted me to build them a bomb, so I took their <a @click="validateLink()" href="example.com/d">plutonium</a> and in turn gave them a shiny bomb case full of used pinball machine parts.

Or alternatively, just instruct Vue.js to run validateLink() whenever any a tag is clicked within the div id="Content" tag.

I can get all the a tags within the div like such:

const AnchorTags = document.getElementById('Content').getElementsByTagName('a');

But I am at a loss of how to then get the validateLink() function to run on click of these tags.

Advertisement

Answer

Content of v-html is treated as plain HTML – you cannot place Vue directives inside.

Luckily for you this specific problem can be solved easily using event delegation e.g. attaching the handler to the parent element + inspecting the target (clicked) element…

const app = Vue.createApp({
  data() {
    return {
      html: `<p>Calm down, Marty, I didn't disintegrate anything. The <a href="example.com/m">molecular structure</a> of Einstein and the car are completely intact. They wanted me to build them a bomb, so I took their <a href="example.com/d">plutonium</a> and in turn gave them a shiny bomb case full of used pinball machine parts.`
    }
  },
  methods: {
    onClick(ev) {
      if(ev.target.tagName === 'A') {
        console.log('Anchor clicked -', ev.target.href)
      }
      
    }
  }
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.2.2/dist/vue.global.js"></script>
<div id='app'>
  <div v-html="html" @click.stop.prevent="onClick">
  </div>
</div>
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement