"How to dynamically render components within a v-for loop triggered by a button from the parent

Is there a way to trigger the rendering of a v-if component by clicking a button inside a v-for loop in the parent element? The component should only render in the item where the button was clicked.

<div v-for="item in items">
  <button @click >Show child</button>
  <div>{{item.name}}</div>
  <child v-if="this button clicked" :item="item"></child>
</div>

Answer №1

In order to keep track of the state of each item, such as whether it has been clicked or not, you will need to store this information in your data object. When a button is clicked, you can update the 'clicked' property for that specific item. Subsequently, if an item's 'clicked' property is set to true, you can display a child component (or any other HTML element).

<template>
  <div>
    <div v-for="item in items" :key="item.id">
      <button @click="item.clicked = true" >Show child</button>
      {{item.name}}
      <div v-if="item.clicked">Item child</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data: function() {
    return {
      items: [
        {
          id: 1,
          name: 'test1',
          clicked: false
        },
        {
          id: 2,
          name: 'test2',
          clicked: false
        },
        {
          id: 3,
          name: 'test3',
          clicked: false
        }
      ]
    }
  }
}
</script>

Answer №2

Simply put, all you need to do is set a flag for later use with the v-if:

<div id="app">
  <div v-for="item in items">
    <button @click="$set(item, 'shown', true)">Show child</button>
    <div>{{ item.name }}</div>
    <div v-if="item.shown">Child component</div>
  </div>
</div>

In this case, $set() is necessary because the initial item may not have the shown field, so setting it directly as item.shown=true won't trigger reactivity.

You can also hide the button after it's clicked:

<button @click="$set(item, 'shown', true)" v-if="!item.shown">Show child</button>

To toggle visibility, you just need to follow this pattern:

<button @click="$set(item, 'shown', !item.shown)">
  {{ item.shown ? 'Hide' : 'Show' }} child
</button>

Check out JSFiddle

Answer №3

Utilizing the item index provided by the v-for directive (e.g. v-for="(item, i) in items") allows you to bind it to a function that controls the visibility of each item by modifying its properties:

Update: The original answer has been removed following further clarification of requirements.

To prevent mutation of items, one approach is to store them in a Map object with visibility settings kept separately as Map values. However, Vue.js currently does not offer reactivity for Map objects, so manual rerendering is required using forceUpdate:

Vue.config.devtools = false;
Vue.config.productionTip = false;
Vue.component('child', {
  template: '<p>Visible child</p>'
})

new Vue({
  el: "#demo",
  template: `
<div>
  <div v-for="item in items">
    <button @click="toggleChild(item)">Toggle child</button>
    <div>{{item.name}}</div>
    <child v-if="isVisible(item)" :item="item"></child>
  </div>
</div>
`,
  data () {
    return {
      itemsMap: new Map(
        [
          { name: 'test1' },
          { name: 'test2' }
        ].map(item => [item, { visible: false }])
      )
    };
  },
  methods: {
    toggleChild(item) {
      this.itemsMap.set(item, { visible: !this.itemsMap.get(item).visible });
      this.$forceUpdate();
    },
    isVisible(item) {
      return this.itemsMap.get(item).visible;
    }
  },
  computed: {
    items: function() {
      return Array.from(this.itemsMap.keys());
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo"></div>

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

The best way to distribute React components within a monorepo using source sharing

I am managing a monorepo with 3 unique React projects: - SHARED_COMPONENTS src Button.tsx package.json - APP_A src main.ts package.json - APP_B src main.ts package.json How can I import the Button(.tsx) module in both main.ts files ...

Dynamic Dot Layout Mapping in Vue.js and Canvas: A Problematic Coordinate Issue

My current project involves using Vue and HTML canvas to create a responsive "link game". You can view a sample of my work in the image below: However, I've encountered a strange issue. I'm trying to determine if a line drawn between two dots is ...

Encountering difficulty accessing the object from the props within the created method

After retrieving an object from an API resource and storing it in a property, I encountered an issue where the children components were unable to access the object inside the created method. This prevented me from assigning the values of the object to my d ...

Exploring Laravel and Vue: A guide to extracting URL parameters in Vue

I have included an id in the URL like this: (). Now, I am trying to retrieve that id in Vue in order to fetch data specifically for that id. However, I am unsure how to obtain the id in Vue. Below is my Vue script: <script> export default ...

Adjusting the background hue of a bootstrap panel

I'm attempting to utilize JavaScript to change the background color of a panel in order to create a "selected" effect. Upon clicking, I retrieve the div by its ID and modify its background color. Although it initially works as intended, the backgrou ...

The processing indicator fails to function properly when trying to refresh a jQuery datatable

I am currently customizing the loading indicator for the datatable using a spinner called startLoadGlobal(SPINNER_DATA_TABLE_FINANCEIRO_CARREGAR_REGISTROS) in jQuery. It works correctly when I initially load the datatable, however, when I reload it, the sp ...

Error: JSON array contains unterminated string literal

Hey there, var favorites = 'Array ( [0] => [" 6 "," 1 "," 2 "," 5 "," 3 "," 4 "] [1] => [" 6 "," 1 "," 2 "," 5 "," 3 "," 4 "] [2] => [" 6 "," 1 "," 2 "," 5 "," 3 "," 4 "] ) '; I've been encountering a syntax error - an untermi ...

The MongoClient.connect method fails to return a valid response

I am currently working with a node.js file that looks like this: var express = require('express'); var app = express(); var mongoClient = require('mongodb').MongoClient; app.get('/',(req, res)=>{ console.log(connect ...

AngularJS displays true for $scope.form.$submitted

I am working on a multi-step form and I am facing an issue with controlling user submissions. I need to validate each step before proceeding to the next one. Even though I am implementing validation checks and moving to the next step accordingly, the $scop ...

The JQUERY Uncaught Error: Syntax error message popped up when trying to access an unrecognized expression on the javascript: void(0)

I've encountered an issue after upgrading to jQuery 3.4.1 while using bootstrap 3. The console keeps showing this error: Uncaught Error: Syntax error, unrecognized expression: # Here is the section of code causing the error: <div class="btn-grou ...

Ajax encounters difficulty in parsing JSON data

I have thoroughly researched similar questions on this topic, but none of them have provided a solution to my problem. My current challenge involves parsing JSON data that is being returned from a PHP script running on the server. I have already used JSON ...

Making adjustments to a row in the free jqGrid is a breeze with the ability

Using free jqGrid 4.12.1, I aim to incorporate functionality for adding, editing, and deleting rows in the grid with server-side calls for each operation. Below is the implementation of editurl and 'actions' formatter, { name: "actions", wi ...

How can one accurately pair the key and its corresponding value from an array of objects to create a new object containing only that key?

In my JavaScript code, I am attempting to create a function that can match a specific key with an array of objects fetched from an API. This matching process is based on two parameters obtained from the API: a key (which is a string) and an array of object ...

Ways to halt the repetition of clicking the like button on my social media posts

I've been working on a new post system that allows users to like posts. Everything seems to be in order except for one issue - when iterating through the likes table from the post-like relation, the like button is being duplicated even with added cond ...

WordPress experiencing issues with AJAX requests resulting in 400 bad request errors

Greetings fellow developers! I've been trying to implement ajax in my WordPress project, but I've hit a roadblock. The console is throwing an error at me: jquery-3.3.1.js:9600 GET http://localhost/wordpress/wp-admin/admin-ajax.php 400 (Bad R ...

Unable to get jQuery function to execute within a JavaScript for-loop. Assistance needed

I've encountered various versions of this problem in the past and just when I believe I have solved it, the issue resurfaces. After some investigation, I was able to identify the root cause, but unfortunately, I'm still unable to find a solution ...

Customize Nuxt default document using a custom app.html file

According to the guidelines provided by Nuxt documentation, you have the ability to customize the default document by... placing an app.html file in the source directory of your project, which is typically the root directory. I followed these instructio ...

Vue JS ensures that it has all the necessary data before proceeding with the

I've been grappling with a VueJS data rendering issue for a few weeks now. My approach involves making axios calls, some nested within others. The problem I'm facing is that the data renders before the calls have completed, resulting in an empty ...

Tips for efficiently printing invoices on specific paper: Print a maximum of 20 items per sheet, and if it exceeds this limit, continue onto the next page. Ensure the total amount is

$(document).ready(function(){ var j = 23; for (var i = 0; i < j+11; i++) { if (i != 0 && i % 11 == 0) { $("#printSection div").append("<?php echo '<tr><td>fff</td></tr>'; ?>"); ...

Error Message: "Attempting to access the 'on' property of an undefined object leading to an error."

While working on my web app and building the server part, I encountered a CMD error that says: TypeError: Cannot read property 'on' of undefined I have already attempted to establish the connection between server.js and client.js, but it s ...