Nested v-for problem confusion

I am encountering an issue with my code and I'm wondering if anyone can help me troubleshoot it. The problem is that whenever I click on the content of one panel, all panel contents with the same index expand or collapse instead of just the one I clicked on. Any suggestions or ideas would be greatly appreciated. Thank you.

<div v-for="(group, i) in groups" :key="i" class="pb-4">
  <p class="text-h5 primary text-center white--text">{{ group.title }}</p>
  <div v-if="group.links">
    <a v-for="(link, u) in group.links" :key="u" :href="link.src" class="black--text"> {{ link.title }}</a>
  </div>
  <v-expansion-panels v-model="activesPanels" multiple accordion dense flat>
    <v-expansion-panel v-for="(item, v) in group.fact" v-show="shouldRender(v)" :key="v">
      <v-expansion-panel-header class="px-0">{{ item.title }}</v-expansion-panel-header>
      <v-expansion-panel-content>
         <type :fact="item" :models="models" />
      </v-expansion-panel-content>
    </v-expansion-panel>
  </v-expansion-panels>
</div>

Answer №1

To resolve the issue, ensure that each group has its own unique v-model variable instead of using the same activesPanels for every group. This will maintain the opening and closing state of each group individually.

Additionally, make sure to use unique properties for template keys to prevent errors such as "Duplicate keys detected."

Check out this working demo:

<!DOCTYPE html>
<html>
  <head>
    <link href="https://cdn.jsdelivr.net/npm/@mdi/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="caaca5a4be8afce4b2">[email protected]</a>/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="88fefdedfce1eef1c8baa6f0">[email protected]</a>/dist/vuetify.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
  </head>
  <body>
    <div id="app">
      <v-app id="inspire">
    <div v-for="(group, i) in groups" :key="i">
  <p class="primary text-center white--text">{{ group.title }}</p>
  <div v-if="group.links">
    <a v-for="link in group.links" :key="link.src" :href="link.src" class="black--text"> {{ link.title }}</a>
  </div>
  <v-expansion-panels v-model="group.activesPanels" multiple accordion dense flat>
    <v-expansion-panel v-for="item in group.fact" :key="item.title">
      <v-expansion-panel-header class="pa-0">{{ item.title }}</v-expansion-panel-header>
      <v-expansion-panel-content class="pa-0">
         Hello
      </v-expansion-panel-content>
    </v-expansion-panel>
  </v-expansion-panels>
</div>
  </v-app>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b1c7c4d4f1839fc9">[email protected]</a>/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="84f2f1e1f0ede2fdc4b6aafc">[email protected]</a>/dist/vuetify.js"></script>
    <script>
      new Vue({
        el: '#app',
        data () {
      return {
        groups: [
        {
          title: "group1",
          activesPanels: [],
          fact: [
            {
              title: 'fact1'
            }
          ],
          links:[
            {
              src: "https://google.com",
              title: "Hello"
            },
            {
              src: "https://twitter.com",
              title: "Hello"
            }
          ]
        },
        {
          title: "group2",
          activesPanels: [],
          fact: [
            {
              title: 'fact2'
            }
          ],
          links:[
            {
              src: "https://www.shorturl.at/",
              title: "Hello"
            },
            {
              src: "https://www.npmjs.com/package/vuex-map-fields",
              title: "Hello"
            }
          ]
        }
      ]
      }
      },
        vuetify: new Vuetify(),
      })
    </script>
  </body>
</html>

Answer №2

Avoid using indexes as keys in your v-for loop to ensure uniqueness for each element. When using index as a key, you may end up with multiple elements having the same index, causing Vue to struggle in tracking DOM changes. This issue worsens when editing the array and changing the indexes of items within it.

Instead, opt for a unique value like an id, link.url, or item.title as your key in the code.

For more details refer to the documentation: https://vuejs.org/guide/essentials/list.html#maintaining-state-with-key

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

Determine whether an element has the capability to hold text content

Is there a surefire and reliable method to determine if an HTML element is capable of holding text, using only pure JavaScript or jQuery? For example, <br>, <hr>, or <tr> cannot contain text nodes, whereas <div>, <td>, or < ...

Is there a way to verify that all of my HTML elements have been loaded in AngularJS?

I am currently utilizing angularJS version 1.2.1 along with angular-ui-bootstrap. Within my code, I have a collection of <ng-includes> tags from angularjs and <accordion> components from angular-ui. When loading the content, I need to initiat ...

Upload multiple files at once, edit span text, and retitle to files chosen

I need help updating the span text for each file uploader on my page. I want the default "Choose a file..." text to change to the selected filename. Can someone assist me with this? Here is a Js fiddle that I've been working on. This is my HTML mark ...

Issue with Jquery: Checkbox fails to get checked in Internet Explorer 7

Having trouble with checking a checkbox, I've attempted the following steps: $('#someId').attr('checked','checked'); $('#someId').attr('checked', true); Both of these methods are effective for I ...

When attempting to import and utilize global state in a component, the error message "Cannot iterate over null object"

I am in the process of setting up a global state to keep track of various properties that I need to pass down to multiple components. const initialState = { username: '', selectedCategory: null, categoriesList: [], createdTaskTopi ...

It requires two clicks on the button for the Vue and Pinia store to update

I've been experimenting with Vue and trying to understand it better. When I click the button in LoginForm.vue for the first time, both token and user_data are null. It's only on the second click that they finally update. How can I ensure these va ...

Accordions housing Bootstrap 3 pills in a sleek design

I'm working on integrating pills and an accordion in Bootstrap 3. Everything seems to be functioning correctly, but there are a couple of issues I am encountering: When the accordion is open, clicking on another tab closes the accordion. I would li ...

Encountered an error when creating my own AngularJS module: Unable to instantiate

Attempting to dive into TypeScript and AngularJS, I encountered a perplexing error after following a tutorial for just a few lines. It appears that there may be an issue with my mydModule? angular.js:68 Uncaught Error: [$injector:modulerr] Failed to inst ...

Using Node to upload various large JSON files into mongoDB

Currently, I am dealing with the task of parsing numerous large JSON files into my mongoDB database. To accomplish this, I have been utilizing the stream-json npm package. The process involves loading one file at a time, then manually changing the filename ...

JavaScript: Repeated Depth First Exploration for hierarchical rearrangement implemented with d3's recursion()

I'm attempting to perform a depth-first search on a complex JSON object, such as the one available through this link. My goal is to generate a modified object structure that looks like this: [ { name: "Original Object", children : [ ...

show tab focus outline only

In search of a straightforward and effective method for focusable elements to display an outline only when the tab key is pressed, without showing it when using a mouse in React applications. (looking for something similar to :focus-visible that function ...

Could not locate module: The package path ./react is not exported from the package in E:NextAppportfolio_website-mainportfolio_website-main ode_modules ext-auth

I am encountering an issue while trying to import SessionProvider from Next-Auth. The error message that is being displayed is: "Module not found: Package path ./react is not exported from package E:\NextApp\portfolio_website-main\port ...

What are the steps to resolve the issue "Error: no valid exports main found" specifically on a Windows 7 operating system?

I've been encountering an issue while attempting to run my react app on Windows 7 OS. I have npm version 6.13.4 and node version 13.6.0 installed on my system. Every time I try to start the application using npm start, I receive the following error co ...

Troubleshooting: Angular 6 Renderer2 Issue with Generating Dynamic DOM Elements for SELECT-Option

Currently, I am attempting to dynamically create a select option using Renderer2. Unfortunately, I am facing difficulties in creating the <Select></Select> element, but I can confirm that the <options> are being successfully created. Due ...

Position a div element after another using the :after pseudo-element

My goal is simple to explain, but I have exhausted all my efforts trying to achieve it. I am hoping for the ★ symbol to appear immediately after the number 06 using jQuery. Any assistance would be greatly appreciated. The numbers are generated by a s ...

Creating a user-friendly interface for the admin to easily upload photos by implementing a php/bootstrap/js code within the panel

I'm currently in the process of creating an online website as part of my thesis project. I've been researching this specific code, but unfortunately, I haven't been able to find a solution. In the admin section of the site, I need to enable ...

JavaScript button is not functioning properly to increase or decrease the value in the input field

I'm facing an issue with the javascript increase/decrease buttons on my website. When I assign my JS variable as the class name of the input field, pressing the button results in all input fields being affected simultaneously: https://i.stack.imgur.c ...

Retrieving a result from a function call is a fundamental aspect of programming

I have a scenario where I am initiating a call from a controller within AngularJS. This call passes some data to a service in order to receive a response that needs to be conditionally checked. Controller patents.forEach(function(item){ // The "patents" ...

What is the proper way to implement ref in typescript?

Currently, I am in the process of learning how to use Vue3 + Typescript. Previously, I have developed Vue2 applications using plain JavaScript. In my current project, I am attempting to define a reactive variable within the setup() function: setup() { ...

Symfony: The Database Query Button with a Pop-up Feature

I am looking to create a button that will automatically search my database for all users with a "secouriste" attribute set and display their first name, last name, and phone number in a popup. After conducting research, here is what I have gathered: In m ...