Skip to content

Commit e1366fd

Browse files
authored
Change vue/valid-v-for and vue/require-v-for-key rules to not report when placing a key on <template> (#1287)
1 parent 1c52bb9 commit e1366fd

File tree

4 files changed

+116
-13
lines changed

4 files changed

+116
-13
lines changed

Diff for: lib/rules/require-v-for-key.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ module.exports = {
3333
* @param {VElement} element The element node to check.
3434
*/
3535
function checkKey(element) {
36+
if (utils.hasDirective(element, 'bind', 'key')) {
37+
return
38+
}
3639
if (element.name === 'template' || element.name === 'slot') {
3740
for (const child of element.children) {
3841
if (child.type === 'VElement') {
3942
checkKey(child)
4043
}
4144
}
42-
} else if (
43-
!utils.isCustomComponent(element) &&
44-
!utils.hasDirective(element, 'bind', 'key')
45-
) {
45+
} else if (!utils.isCustomComponent(element)) {
4646
context.report({
4747
node: element.startTag,
4848
loc: element.startTag.loc,

Diff for: lib/rules/valid-v-for.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ function checkChildKey(context, vFor, child) {
7070
* @param {VElement} element The element node to check.
7171
*/
7272
function checkKey(context, vFor, element) {
73-
if (element.name === 'template') {
73+
const vBindKey = utils.getDirective(element, 'bind', 'key')
74+
75+
if (vBindKey == null && element.name === 'template') {
7476
for (const child of element.children) {
7577
if (child.type === 'VElement') {
7678
checkChildKey(context, vFor, child)
@@ -79,8 +81,6 @@ function checkKey(context, vFor, element) {
7981
return
8082
}
8183

82-
const vBindKey = utils.getDirective(element, 'bind', 'key')
83-
8484
if (utils.isCustomComponent(element) && vBindKey == null) {
8585
context.report({
8686
node: element.startTag,

Diff for: tests/lib/rules/require-v-for-key.js

+52
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,58 @@ tester.run('require-v-for-key', rule, {
5656
filename: 'test.vue',
5757
code:
5858
'<template><div><slot v-for="x in list" :name="x"><div :key="x"></div></slot></div></template>'
59+
},
60+
// key on <template> : In Vue.js 3.x, you can place key on <template>.
61+
{
62+
filename: 'test.vue',
63+
code:
64+
'<template><div><template v-for="x in list" v-bind:key="x"><div /></template></div></template>'
65+
},
66+
{
67+
filename: 'test.vue',
68+
code:
69+
'<template><div><template v-for="x in list" v-bind:key="x"><MyComp /></template></div></template>'
70+
},
71+
{
72+
filename: 'test.vue',
73+
code:
74+
'<template><div><template v-for="x in list" :key="x"><div /></template></div></template>'
75+
},
76+
{
77+
filename: 'test.vue',
78+
code:
79+
'<template><div><template v-for="x in list" :key="x"><MyComp /></template></div></template>'
80+
},
81+
{
82+
filename: 'test.vue',
83+
code:
84+
'<template><div><template v-for="x in list" :key="x.id"><div /></template></div></template>'
85+
},
86+
{
87+
filename: 'test.vue',
88+
code:
89+
'<template><div><template v-for="x in list" :key="x.id"><MyComp /></template></div></template>'
90+
},
91+
{
92+
filename: 'test.vue',
93+
code:
94+
'<template><div><template v-for="(x, i) in list" :key="i"><div /></template></div></template>'
95+
},
96+
{
97+
filename: 'test.vue',
98+
code:
99+
'<template><div><template v-for="(x, i) in list" :key="i"><MyComp /></template></div></template>'
100+
},
101+
// key on <slot> : In Vue.js 3.x, you can place key on <slot>.
102+
{
103+
filename: 'test.vue',
104+
code:
105+
'<template><div><slot v-for="x in list" :key="x"><div /></slot></div></template>'
106+
},
107+
{
108+
filename: 'test.vue',
109+
code:
110+
'<template><div><slot v-for="x in list" :key="x"><MyComp /></slot></div></template>'
59111
}
60112
],
61113
invalid: [

Diff for: tests/lib/rules/valid-v-for.js

+57-6
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,63 @@ tester.run('valid-v-for', rule, {
128128
</template>
129129
`
130130
},
131+
// key on <template> : In Vue.js 3.x, you can place key on <template>.
132+
{
133+
filename: 'test.vue',
134+
code:
135+
'<template><div><template v-for="x in list" v-bind:key="x"><div /></template></div></template>'
136+
},
137+
{
138+
filename: 'test.vue',
139+
code:
140+
'<template><div><template v-for="x in list" v-bind:key="x"><MyComp /></template></div></template>'
141+
},
142+
{
143+
filename: 'test.vue',
144+
code:
145+
'<template><div><template v-for="x in list" :key="x"><div /></template></div></template>'
146+
},
147+
{
148+
filename: 'test.vue',
149+
code:
150+
'<template><div><template v-for="x in list" :key="x"><MyComp /></template></div></template>'
151+
},
152+
{
153+
filename: 'test.vue',
154+
code:
155+
'<template><div><template v-for="x in list" :key="x.id"><div /></template></div></template>'
156+
},
157+
{
158+
filename: 'test.vue',
159+
code:
160+
'<template><div><template v-for="x in list" :key="x.id"><MyComp /></template></div></template>'
161+
},
162+
{
163+
filename: 'test.vue',
164+
code:
165+
'<template><div><template v-for="(x, i) in list" :key="i"><div /></template></div></template>'
166+
},
167+
{
168+
filename: 'test.vue',
169+
code:
170+
'<template><div><template v-for="(x, i) in list" :key="i"><MyComp /></template></div></template>'
171+
},
172+
{
173+
filename: 'test.vue',
174+
code:
175+
'<template><div><template v-for="x in list" :key="x"><custom-component></custom-component></template></div></template>'
176+
},
177+
// key on <slot> : In Vue.js 3.x, you can place key on <slot>.
178+
{
179+
filename: 'test.vue',
180+
code:
181+
'<template><div><slot v-for="x in list" :key="x"><div /></slot></div></template>'
182+
},
183+
{
184+
filename: 'test.vue',
185+
code:
186+
'<template><div><slot v-for="x in list" :key="x"><MyComp /></slot></div></template>'
187+
},
131188
// parsing error
132189
{
133190
filename: 'parsing-error.vue',
@@ -254,12 +311,6 @@ tester.run('valid-v-for', rule, {
254311
"Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."
255312
]
256313
},
257-
{
258-
filename: 'test.vue',
259-
code:
260-
'<template><div><template v-for="x in list" :key="x"><custom-component></custom-component></template></div></template>',
261-
errors: ["Custom elements in iteration require 'v-bind:key' directives."]
262-
},
263314
{
264315
filename: 'test.vue',
265316
code:

0 commit comments

Comments
 (0)