Skip to content

Commit

Permalink
warn v-for component lists without explicit keys
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jan 24, 2017
1 parent f33ca99 commit 5ae63d9
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 8 deletions.
12 changes: 12 additions & 0 deletions src/compiler/codegen/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}){` +
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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> (
Expand Down
2 changes: 1 addition & 1 deletion src/entries/web-runtime-with-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion test/unit/features/component/component-async.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]
},
Expand Down
2 changes: 1 addition & 1 deletion test/unit/features/component/component-slot.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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>'
Expand Down
2 changes: 1 addition & 1 deletion test/unit/features/component/component.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' }]
Expand Down
17 changes: 15 additions & 2 deletions test/unit/features/directives/for.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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>',
Expand Down Expand Up @@ -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: {
Expand All @@ -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: {
Expand Down
2 changes: 1 addition & 1 deletion test/unit/features/ref.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down

0 comments on commit 5ae63d9

Please sign in to comment.