warn v-for component lists without explicit keys

This commit is contained in:
Evan You 2017-01-24 16:04:14 -05:00
parent f33ca991ac
commit 5ae63d9d2f
8 changed files with 33 additions and 8 deletions

View File

@ -144,6 +144,18 @@ function genFor (el: any): string {
const alias = el.alias
const iterator1 = el.iterator1 ? `,${el.iterator1}` : ''
const iterator2 = el.iterator2 ? `,${el.iterator2}` : ''
if (
process.env.NODE_ENV !== 'production' &&
maybeComponent(el) && el.tag !== 'slot' && el.tag !== 'template' && !el.key
) {
warn(
`<${el.tag} v-for="${alias} in ${exp}">: component lists rendered with ` +
`v-for should have explicit keys. ` +
`See https://vuejs.org/guide/list.html#key for more info.`
)
}
el.forProcessed = true // avoid recursion
return `_l((${exp}),` +
`function(${alias}${iterator1}${iterator2}){` +

View File

@ -3,7 +3,7 @@
import { parseFilters } from './parser/filter-parser'
export function baseWarn (msg: string) {
console.error(`[Vue parser]: ${msg}`)
console.error(`[Vue compiler]: ${msg}`)
}
export function pluckModuleFunction<F: Function> (

View File

@ -55,7 +55,7 @@ Vue.prototype.$mount = function (
}
if (template) {
const { render, staticRenderFns } = compileToFunctions(template, {
warn,
warn: msg => warn(msg, this),
shouldDecodeNewlines,
delimiters: options.delimiters
}, this)

View File

@ -110,7 +110,7 @@ describe('Component async', () => {
it('with v-for', done => {
const vm = new Vue({
template: '<div><test v-for="n in list" :n="n"></test></div>',
template: '<div><test v-for="n in list" :key="n" :n="n"></test></div>',
data: {
list: [1, 2, 3]
},

View File

@ -243,7 +243,7 @@ describe('Component slot', () => {
it('combined with v-for', () => {
const vm = new Vue({
template: '<div><test v-for="i in 3">{{ i }}</test></div>',
template: '<div><test v-for="i in 3" :key="i">{{ i }}</test></div>',
components: {
test: {
template: '<div><slot></slot></div>'

View File

@ -166,7 +166,7 @@ describe('Component', () => {
const vm = new Vue({
template:
'<div>' +
'<component v-for="c in comps" :is="c.type"></component>' +
'<component v-for="c in comps" :key="c.type" :is="c.type"></component>' +
'</div>',
data: {
comps: [{ type: 'one' }, { type: 'two' }]

View File

@ -348,7 +348,7 @@ describe('Directive v-for', () => {
},
template:
'<div>' +
'<test v-for="item in list" :msg="item.a">' +
'<test v-for="item in list" :msg="item.a" :key="item.a">' +
'<span>{{item.a}}</span>' +
'</test>' +
'</div>',
@ -387,7 +387,7 @@ describe('Directive v-for', () => {
},
template:
'<div>' +
'<component v-for="item in list" :is="item.type"></component>' +
'<component v-for="item in list" :key="item.type" :is="item.type"></component>' +
'</div>',
components: {
one: {
@ -405,6 +405,19 @@ describe('Directive v-for', () => {
}).then(done)
})
it('should warn component v-for without keys', () => {
new Vue({
template: `<div><test v-for="i in 3"></test></div>`,
components: {
test: {
render () {}
}
}
}).$mount()
expect('<test v-for="i in 3">: component lists rendered with v-for should have explicit keys')
.toHaveBeenWarned()
})
it('multi nested array reactivity', done => {
const vm = new Vue({
data: {

View File

@ -121,7 +121,7 @@ describe('ref', () => {
},
template: `
<div>
<test v-for="n in items" ref="list" :n="n"></test>
<test v-for="n in items" ref="list" :key="n" :n="n"></test>
</div>
`,
components: {