Skip to content

noVueUndeclaredProperties (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueUndeclaredProperties": "error"
}
}
}
}

Disallow using properties that a Vue component doesn’t declare.

A component’s template and its this can only use what the component declares: its props, data, computed properties, methods, injected values, the values its setup() function returns, and the variables of <script setup>. Using any other name gives undefined. This usually means the name has a typo, or the declaration was removed or never written.

This rule reports such names in the template, in this.name inside the component’s options, and in props.name when props is the object returned by defineProps() or passed to setup(). It also reports names written as strings in the watch and expose options, and members that a data property doesn’t have when its value is an object written in place, such as user.nmae when data() returns { user: { name: "" } }.

Names that start with $, such as $route or $t, are never reported, because plugins commonly add properties with these names to every component.

The rule reports nothing for a component when it can’t know everything the component declares. That is the case when:

  • the component uses mixins or extends;
  • an object is copied into the options with ..., as in computed: { ...mapState(["user"]) };
  • an option such as data or setup returns something other than an object written in place, as in return toRefs(state);
  • the props are declared with a TypeScript type that is imported from another file;
  • the component has a <script src> block.
import { defineComponent } from "vue";
export default defineComponent({
data() {
return { count: 0 };
},
methods: {
increment() {
this.cnt++;
},
},
});
code-block.js:9:12 lint/nursery/noVueUndeclaredProperties ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ cnt isn't declared by this component.

7 │ methods: {
8 │ increment() {
> 9 │ this.cnt++;
│ ^^^
10 │ },
11 │ },

ℹ Vue doesn't track changes to it, so the page doesn't update when it changes.

ℹ This often means the name has a typo, or its declaration is missing.

ℹ Fix the name, or declare it in the component.

ℹ 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 props = defineProps(["name"]);
console.log(props.title);
</script>
code-block.vue:3:19 lint/nursery/noVueUndeclaredProperties ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ title isn't declared as a prop of this component.

1 │ <script setup>
2 │ const props = defineProps(["name"]);
> 3 │ console.log(props.title);
│ ^^^^^
4 │ </script>
5 │

ℹ Its value is always undefined.

ℹ This often means the name has a typo, or its declaration is missing.

ℹ Fix the name, or declare it in the component.

ℹ 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 count = 0;
</script>
<template>
<p>{{ cnt }}</p>
</template>
<script>
export default {
props: ["name"],
data() {
return { count: 0 };
},
methods: {
increment() {
this.count++;
},
},
};
</script>
<template>
<button @click="increment">{{ name }}: {{ count }} {{ $t("clicks") }}</button>
</template>

A list of property names that are never reported. Use it for properties that a plugin adds to every component, when their names don’t start with $.

Default: []

biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueUndeclaredProperties": {
"level": "on",
"options": {
"ignore": [
"i18n"
]
}
}
}
}
}
}
import { defineComponent } from "vue";
export default defineComponent({
methods: {
greet() {
return this.i18n.translate("hello");
},
},
});