Skip to content

Commit

Permalink
Change vue/valid-v-for and vue/require-v-for-key rules to not rep…
Browse files Browse the repository at this point in the history
…ort when placing a key on `<template>` (#1287)
  • Loading branch information
ota-meshi committed Aug 28, 2020
1 parent 1c52bb9 commit e1366fd
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 13 deletions.
8 changes: 4 additions & 4 deletions lib/rules/require-v-for-key.js
Expand Up @@ -33,16 +33,16 @@ module.exports = {
* @param {VElement} element The element node to check.
*/
function checkKey(element) {
if (utils.hasDirective(element, 'bind', 'key')) {
return
}
if (element.name === 'template' || element.name === 'slot') {
for (const child of element.children) {
if (child.type === 'VElement') {
checkKey(child)
}
}
} else if (
!utils.isCustomComponent(element) &&
!utils.hasDirective(element, 'bind', 'key')
) {
} else if (!utils.isCustomComponent(element)) {
context.report({
node: element.startTag,
loc: element.startTag.loc,
Expand Down
6 changes: 3 additions & 3 deletions lib/rules/valid-v-for.js
Expand Up @@ -70,7 +70,9 @@ function checkChildKey(context, vFor, child) {
* @param {VElement} element The element node to check.
*/
function checkKey(context, vFor, element) {
if (element.name === 'template') {
const vBindKey = utils.getDirective(element, 'bind', 'key')

if (vBindKey == null && element.name === 'template') {
for (const child of element.children) {
if (child.type === 'VElement') {
checkChildKey(context, vFor, child)
Expand All @@ -79,8 +81,6 @@ function checkKey(context, vFor, element) {
return
}

const vBindKey = utils.getDirective(element, 'bind', 'key')

if (utils.isCustomComponent(element) && vBindKey == null) {
context.report({
node: element.startTag,
Expand Down
52 changes: 52 additions & 0 deletions tests/lib/rules/require-v-for-key.js
Expand Up @@ -56,6 +56,58 @@ tester.run('require-v-for-key', rule, {
filename: 'test.vue',
code:
'<template><div><slot v-for="x in list" :name="x"><div :key="x"></div></slot></div></template>'
},
// key on <template> : In Vue.js 3.x, you can place key on <template>.
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" v-bind:key="x"><div /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" v-bind:key="x"><MyComp /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x"><div /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x"><MyComp /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x.id"><div /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x.id"><MyComp /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="(x, i) in list" :key="i"><div /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="(x, i) in list" :key="i"><MyComp /></template></div></template>'
},
// key on <slot> : In Vue.js 3.x, you can place key on <slot>.
{
filename: 'test.vue',
code:
'<template><div><slot v-for="x in list" :key="x"><div /></slot></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><slot v-for="x in list" :key="x"><MyComp /></slot></div></template>'
}
],
invalid: [
Expand Down
63 changes: 57 additions & 6 deletions tests/lib/rules/valid-v-for.js
Expand Up @@ -128,6 +128,63 @@ tester.run('valid-v-for', rule, {
</template>
`
},
// key on <template> : In Vue.js 3.x, you can place key on <template>.
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" v-bind:key="x"><div /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" v-bind:key="x"><MyComp /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x"><div /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x"><MyComp /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x.id"><div /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x.id"><MyComp /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="(x, i) in list" :key="i"><div /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="(x, i) in list" :key="i"><MyComp /></template></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x"><custom-component></custom-component></template></div></template>'
},
// key on <slot> : In Vue.js 3.x, you can place key on <slot>.
{
filename: 'test.vue',
code:
'<template><div><slot v-for="x in list" :key="x"><div /></slot></div></template>'
},
{
filename: 'test.vue',
code:
'<template><div><slot v-for="x in list" :key="x"><MyComp /></slot></div></template>'
},
// parsing error
{
filename: 'parsing-error.vue',
Expand Down Expand Up @@ -254,12 +311,6 @@ tester.run('valid-v-for', rule, {
"Expected 'v-bind:key' directive to use the variables which are defined by the 'v-for' directive."
]
},
{
filename: 'test.vue',
code:
'<template><div><template v-for="x in list" :key="x"><custom-component></custom-component></template></div></template>',
errors: ["Custom elements in iteration require 'v-bind:key' directives."]
},
{
filename: 'test.vue',
code:
Expand Down

0 comments on commit e1366fd

Please sign in to comment.