Skip to content
42 changes: 36 additions & 6 deletions docs/rules/no-template-shadow.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,51 @@ This rule aims to eliminate shadowed variable declarations of v-for directives o
</template>

<script>
export default {
data () {
return {
l: false
}
export default {
data() {
return {
l: false
}
}
}
</script>
```

</eslint-code-block>

## :wrench: Options

Nothing.
This rule takes one optional object option, with the property `"allow"`.

```json
{
"no-template-shadow": ["error", { "allow": [] }]
}
```

- `"allow"` (`[string]`) Array of identifier names for which shadowing is allowed.

Examples of correct code for the `{ "allow": ["i"] }` option:

<eslint-code-block :rules="{'vue/no-template-shadow': ['error', { allow: ['i'] }]}">

```vue
<template>
<div v-for="i in 5"></div>
</template>

<script>
export default {
data() {
return {
i: 'some value'
}
}
}
</script>
```

</eslint-code-block>

## :rocket: Version

Expand Down
28 changes: 27 additions & 1 deletion lib/rules/no-template-shadow.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ const GROUP_NAMES = [
'setup'
]

function isAllowedVarName(context, variableName) {
if (context.options[0] && context.options[0].allow) {
return context.options[0].allow.includes(variableName)
}
return false
}

module.exports = {
meta: {
type: 'suggestion',
Expand All @@ -30,7 +37,21 @@ module.exports = {
url: 'https://eslint.vuejs.org/rules/no-template-shadow.html'
},
fixable: null,
schema: [],
schema: [
{
type: 'object',
properties: {
allow: {
type: 'array',
items: {
type: 'string'
},
uniqueItems: true
}
},
additionalProperties: false
}
],
messages: {
alreadyDeclaredInUpperScope:
"Variable '{{name}}' is already declared in the upper scope."
Expand Down Expand Up @@ -102,6 +123,11 @@ module.exports = {
for (const variable of node.variables) {
const varNode = variable.id
const name = varNode.name

if (isAllowedVarName(context, name)) {
continue
}

if (
scopeStack.nodes.some((node) => node.name === name) ||
jsVars.has(name)
Expand Down
15 changes: 15 additions & 0 deletions tests/lib/rules/no-template-shadow.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ ruleTester.run('no-template-shadow', rule, {
defineProps({k:Number})
</script>
`
},
{
filename: 'test.vue',
code: `
<template>
<div v-for="i in 5">
<div v-for="i in 5">
</div>
</div>
</template>
<script setup>
defineProps({i:Number})
</script>
`,
options: [{ allow: ['i'] }]
}
],

Expand Down