I would like to ask if someone see the problem in my code. Everything render ok, no problem with the render, the issue is that every time I click in one panel content all the panel-content of every group with the same index expand or collapse and not only the one that I clicked. Any idea?? Thanks a lot.
<div v-for="(group, i) in groups" :key="i" >
<p >{{ group.title }}</p>
<div v-if="group.links">
<a v-for="(link, u) in group.links" :key="u" :href="link.src" > {{ 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 >{{ 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>
CodePudding user response:
You should avoid using indexes as keys in your v-for loop. The keys need to be unique for every element. By using index you have probably 2 elements with index 0 as a key. Vue cannot keep track of changes in the DOM that way. It is getting even worse if you edit the array and items in the array get another index.
So, you can use a unique value for the key, maybe an id or link.url
and item.title
in your code.
See docs: https://vuejs.org/guide/essentials/list.html#maintaining-state-with-key
CodePudding user response:
The reason for this issue is that you are using the same v-model variable activesPanels
for every group. The activesPanels
should belong to each group to maintain their opening and closing state individually.
Also, use the unique properties for template keys to avoid errors i.e, "Duplicate keys detected".
Here is the working demo-
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/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 >{{ group.title }}</p>
<div v-if="group.links">
<a v-for="link in group.links" :key="link.src" :href="link.src" > {{ 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 >{{ item.title }}</v-expansion-panel-header>
<v-expansion-panel-content >
Hello
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</div>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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>