Implementing event handlers with 'v-on' on dynamically inserted content using 'v-html' in Vue

Can Vue allow for the addition of v-on events on strings included in v-html? In this scenario, clicking the 'Maggie' link doesn't produce any action. It appears that it's not recognized by Vue.

Is there an alternative method to achieve this? I am currently using Vue.js version 2.1.3

Javascript

window.onload = function() {
    new Vue({
        el: '#app',
        data: {
            users: ['Homer', 'Marge', 'Bart', 'Lisa', '<a href="#" v-on:click="click_user">Maggie</a>']
        },
        methods: {
            click_user: function() {
                console.log('Click user')
            },
        }
    })
}

HTML

<div id="app">
    <div v-for="user in users" v-html="user"></div><br>
    <a href="#" v-on:click="click_user">This works.</a>
</div>

Answer №1

According to the information provided in the vue documentation:

The innerHTML of an element can be updated using the v-html directive. It is important to note that the content will be inserted as plain HTML and not compiled as Vue templates. If there is a need to create templates using v-html, it is recommended to reconsider the approach by utilizing components instead.

It should be noted that v-on will not function within v-html because it relies on Vue for functionality.


A Possible Resolution for Your Specific Issue

To conditionally display a link by using v-if, or else render plain text.

new Vue({
  el: '#app',
  data: {
    users: [
      { name: 'Homer', clickable: false },
      { name: 'Marge', clickable: false },
      { name: 'Bart', clickable: false },
      { name: 'Lisa', clickable: false },
      { name: 'Maggie', clickable: true },
    ]
  },
  methods: {
    click_user: function() {
      console.log('Click user')
    },
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.0/vue.js"></script>

<div id="app">
  <div v-for="user in users">
    <div v-if="!user.clickable">{{user.name}}</div>
    <a v-if="user.clickable" href="#" v-on:click="click_user">{{user.name}}</a>
  </div>
</div>

Answer №2

When using v-html to render

<a href="#" v-on:click="click_user">Maggie</a>
, the click event will not be bound. More information can be found in the official documentation. The v-on:click will simply render as an attribute.

It's recommended to keep a simple array of data and avoid using v-html. Instead, use either text or index with if (for one or two conditions) or switch (for multiple conditions) to trigger events.

window.onload = function() {
    new Vue({
        el: '#app',
        data: {
            users: ['Homer', 'Marge', 'Bart', 'Lisa', 'Maggie']
        },
        methods: {
            click_user: function(text) {
              if(text=='Maggie') console.log('Click user')
            }
        }
    })
}

<div id="app">
   <div v-for="user in users" v-on:click="click_user(user)">{{user.name}}</div><br>    
</div>

Alternatively,

window.onload = function( ) {
  new Vue({
      el: '#app',
      data: {
          users: ['Homer', 'Marge', 'Bart', 'Lisa', 'Maggie']
      },
      methods: {
        click_user: function(index) {
          if(index==4) console.log('Click user')
        }
      }
   })
}

<div id="app">
   <div v-for="user,index in users" v-on:click="click_user(index)">{{user.name}}</div><br>    
 </div>

Answer №3

To enhance your code, consider creating a component and passing the user variable as a prop. Take a look at this example:

<users-list v-for="user in users" v-bind:user="user"></users-list>

For a functional demonstration, check out this link: https://jsfiddle.net/leocoder/tor13m26/1/

Avoid using v-html for this purpose as it is considered a bad practice.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Pressing a key once causing two actions when managing content in a separate window

Issue: I am facing a problem where I receive double keypresses from one key event when the event updates content in two separate windows. (Please keep in mind that I am not an expert in this field and appreciate your understanding.) I am attempting to use ...

Convert the JSON data received from a jQuery AJAX call into a visually appealing HTML table

Utilizing AJAX as the action, I have created a search form. In the success of the AJAX request, I am seeking a way to update a specific div without refreshing the entire page. Below is my form: <?php $properties = array('id' => &ap ...

Using the "@" symbol as an alias in computed properties with Vue2

Is it feasible to utilize the @ src alias within a computed property? I couldn't find any information on this. My aim is to assign an img src dynamically depending on the component type. However, the computed property only seems to return a static st ...

Preventing users from inputting the symbols "+" or "-" in a React JS input field

Essentially, the input field should only accept values between 1 and 999 Input Field : <input type="number" value={value} onChange={this.props.onViltMaxUserChange} min="0" max="999" /> onChange : onViltMaxUserChange = _.throttle(e = ...

Reverse changes made to a massive object and then redo them

My current project requires the implementation of undo-redo functionality for a product. At the moment, I am managing a substantial Object retrieved from a MongoDB collection The structure is as follows: { cart:{ products:[ { name: " ...

Angular code is malfunctioning and not delivering the expected results

I currently have setup the code below: var videoControllers = angular.module('videoControllers', []); videoControllers.videoControllers('VideoDetailController', function($scope, $routeParams, $http){ $http.get('http://localho ...

What could be causing my Alert component to keep triggering repeatedly?

This is my custom React Native script. import React, { useState, useEffect } from 'react'; import { Alert, View, Image, StyleSheet, Animated, Easing, TouchableOpacity, Text, ScrollView, ImageBackground, Dimensions, TextInput } from 'react-na ...

Increasing the nth-child Selector in Jquery

Referring to this I am looking to cycle through the nth-child selector, which involves: var i = 1; var tmp = $(this).find('td:nth-child(i+1)'); // I wonder how this can be achieved i++; I have rows with dynamically generated columns i ...

Module child-process not found

Why is it that when I try to run "require('child-process')" in the node shell, I receive an error saying "Cannot find module 'child-process'"? It seems like "child-process" should be a default library in Node. Any insights on what could ...

Should the Express.js router be required directly or stored in a variable before use?

I've been pondering a performance question related to express.js. In my server.js file, I have all the routes defined and the child routes are imported as follows: const ROUTE__FOO = require('./routes/foo') const ROUTE__BAR = require(' ...

An unassigned variable automatically sets the disabled attribute to true on an input field

Is this behavior a problem or normal? Consider the following form structure: <form #form="ngForm" > <div> <label>field1</label> <input type="text" name="field1" [(ngModel)]="mainVar" [disabled]="someVar" /> ...

How can you retrieve the original file name and line number in exceptions that are generated in Angular controllers?

When an error occurs in my Angular controller, a stack trace is generated that typically looks like the following: TypeError: undefined is not a function at new <anonymous> (…/dist/script.js:854:5) at invoke (…/dist/base-script.js:13441: ...

Is there a way to bring together scrolling effects and mouse movement for a dynamic user

If you want to see a scrolling effect, check out this link here. For another animation on mouse move, click on this link(here). Combining both the scrolling effect and the image movement might seem challenging due to different styles used in each templat ...

Transform an angular1 javascript circular queue implementation for calculating rolling averages into typescript

I am currently in the process of migrating a project from Angular 1 to Angular 2. One of the key components is a chart that displays a moving average line, which requires the use of a circular queue with prototype methods like add, remove, and getAverage. ...

Implementing pagination using getServerSideProps in NextJS allows for dynamic

I'm currently using NextJS along with Supabase for my database needs. I'm facing a challenge with implementing pagination as the solution I'm seeking involves passing queries to the API. However, since I'm fetching data directly from th ...

Mobile devices are unable to properly implement the Jquery show/hide feature

Currently, I am working on a small Russian project and facing some challenges with the mobile version of my website: php8098.github.io/breakfast. The issue lies within the first slider where the play button should trigger a modal window to open. I urgentl ...

Avoid changing the regex pattern if it is surrounded by a specific character

I want to change all occurrences of strings enclosed by - with strings enclosed by ~, unless the string is again surrounded by *. For instance, consider this string... The -quick- *brown -f-ox* jumps. ...should be altered to... The ~quick~ *brown -f-ox ...

Console displays null as the attribute value

When I check the console, I notice that the data-postid attribute is displaying 'null'. What could be causing this issue? I would like to view the data-id in the console when clicking on the button with the id modal-save. I have reviewed my cod ...

show image with the help of jquery and ajax

To showcase company information along with an image, I have a controller set up as follows: public JsonResult DisplayCompanyDetails() { CompanyModel cm = new CompanyModel(); string query = "select CompanyName,Address,Conta ...

Challenges arising from the rendering of main.js in Vue.js

Recently, I started working with Vue and am now faced with the task of maintaining a project. Main.js contains the routing structure: Main.js import Vue from 'vue' const app = new Vue({ el: '#app', data: { message: & ...