Skip to content

noVueTemplateShadow (HTML)

Language HTML
biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueTemplateShadow": "error"
}
}
}
}

Disallow template variables that reuse the name of a variable from an outer scope.

v-for and v-slot create variables that only exist inside their element. When one of these variables has the same name as a variable the template can already see, the new variable hides the old one. Inside the element, the name always refers to the new variable, so the outer value can’t be used there, and readers can easily confuse the two.

The variables that can be hidden are:

  • variables created by an enclosing v-for or v-slot;
  • top-level variables and imports of <script setup>;
  • what the component exposes to its template: props, models created with defineModel(), data, asyncData, computed properties, methods, injected values, and the values returned by setup().

Types declared in <script setup lang="ts"> are not variables, so a template variable can reuse their names.

<template>
<div v-for="item in groups">
<span v-for="item in item.children">{{ item }}</span>
</div>
</template>
code-block.vue:3:18 lint/nursery/noVueTemplateShadow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ The template variable item hides a variable with the same name.

1 │ <template>
2 │ <div v-for="item in groups">
> 3 │ <span v-for="item in item.children">{{ item }}</span>
│ ^^^^
4 │ </div>
5 │ </template>

ℹ The hidden item is declared here.

1 │ <template>
> 2 │ <div v-for="item in groups">
│ ^^^^
3 │ <span v-for="item in item.children">{{ item }}</span>
4 │ </div>

ℹ Inside this element, item refers to the template variable, so the other item can't be used, and the two are easy to confuse.

ℹ Rename the template variable.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
const item = "selected";
</script>
<template>
<div v-for="item in items">{{ item }}</div>
</template>
<template>
<div v-for="group in groups">
<span v-for="child in group.children">{{ child }}</span>
</div>
<div v-for="group in otherGroups">{{ group }}</div>
</template>

Type: string[]

Default: []

A list of names that template variables may reuse. A variable with one of these names is never reported.

biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueTemplateShadow": {
"level": "on",
"options": {
"allow": [
"item"
]
}
}
}
}
}
}
<template>
<div v-for="item in groups">
<span v-for="item in item.children">{{ item }}</span>
</div>
</template>