Vue: nested v-for by component and template bug

Created on 29 Sep 2016  路  4Comments  路  Source: vuejs/vue

Vue.js version

2.0-rc8 / 2.0-rc7

Reproduction Link

https://codepen.io/toxic-johann/pen/JRJgGJ?editors=1111

Steps to reproduce

use a v-for to render component
in component, you have to write a v-for with template in it but not wrapped with a root element
open console, and run test() function

What is Expected?

open console, and run success() function
or you can click https://codepen.io/toxic-johann/pen/JRJgGJ?editors=1111.
when i keep on one root element in v-for, the problem dispear.

So I think, if vue consider multiple element int the template is forbidden.It should throw a warn.
Otherwise, it's a bug

What is actually happening?

throw the warning

[Vue warn]: It seems there are duplicate keys that is causing an update error. Make sure each v-for item has a unique key.
and error
Uncaught (in promise) TypeError: Cannot read property 'tag' of undefined

it's the same problem with https://github.com/vuejs/vue/issues/3807
u can reopen that.

Most helpful comment

with two keyed children inside v-for we'll also get error about duplicate keys:
[Vue warn]: Duplicate keys detected: '1234'. This may cause an update error.

<div v-for="toy in child.toys">
    <div :key="toy.id"> </div>
    <div :key="toy.id"> </div>
</div>

in order to avoid that we need to add some thing to that keys

<div v-for="toy in child.toys">
    <div :key="toy.id + '-first'"> </div>
    <div :key="toy.id + '-second'"> </div>
</div>

All 4 comments

It actually works when v-if="toy.name != 'b'" is replaced with with v-else

<template v-for="toy in child.toys">
  <template v-if="toy.name == 'b'" :key="toy.id"> 
    <p>toy a</p>
  </template>
  <template v-else :key="toy.id"> 
    <p>toy b</p>
  </template>
</template>

https://codepen.io/fnlctrl/pen/XjaXPa?editors=1011

It also works when the inner <template> is replaced with <div>

<template v-for="toy in child.toys">
     <div v-if="toy.name == 'b'" :key="toy.id"> 
         <p>toy a</p>
     </div>
     <div v-if="toy.name != 'b'" :key="toy.id"> 
        <p>toy b</p>
     </div>
</template>

https://codepen.io/fnlctrl/pen/jrLWQq?editors=1011

And it works when the outer<template> is replaced with <div>

<div v-for="toy in child.toys">
    <template v-if="toy.name == 'b'" :key="toy.id"> 
        <p>toy a</p>
    </template>
    <template v-if="toy.name != 'b'" :key="toy.id"> 
        <p>toy b</p>
    </template>
</div>

https://codepen.io/fnlctrl/pen/KgvVJg?editors=1111

So I guess it's using multiple <template>s inside a v-fored <template> that caused the problem, but I doubt if it's the root cause, because I don't think keying a <template> should be valid..
If not, it should indeed be warned about.

yes, u r right.
However, in my program, i have to use multi template.Which may cause nested template with v-for and multiple v-if (more than 2 condition, which make me can not use v-else).So i run into this problem. I can add a normal div to prevent the problem.But that may bring too many meaningless tag.
So i now control the switch with nextTick to avoid these problem.
BTW, i do not use key in the real program ,but it run well.So i don't think it's the key problem.I agree that it's a template problem more.

thank you~

with two keyed children inside v-for we'll also get error about duplicate keys:
[Vue warn]: Duplicate keys detected: '1234'. This may cause an update error.

<div v-for="toy in child.toys">
    <div :key="toy.id"> </div>
    <div :key="toy.id"> </div>
</div>

in order to avoid that we need to add some thing to that keys

<div v-for="toy in child.toys">
    <div :key="toy.id + '-first'"> </div>
    <div :key="toy.id + '-second'"> </div>
</div>
Was this page helpful?
0 / 5 - 0 ratings