Skip to content

vue/no-props-shadow ​

disallow declarations that shadow props in <script setup>

  • ❗ This rule has not been released yet.

📖 Rule Details ​

This rule reports top-level declarations in <script setup> that have the same name as a prop.

In <script setup> the props and the top-level bindings of the script are both exposed to the template. When a local binding has the same name as a prop, it is ambiguous which of the two the template renders, and the answer (the local binding wins) is rarely what the author expected.

Now loading...

The rule reports every kind of top-level binding, because they all reach the template: const, let, var, function declarations, class declarations and imports.

The following are not reported:

  • The binding that holds the result of defineProps(), including the destructured form. Those bindings are the props, so they cannot shadow them.

    Now loading...
    Now loading...
  • Declarations in nested scopes. A variable inside a function body or a block is not exposed to the template, so it cannot make the template ambiguous.

    Now loading...
  • Type-only declarations, such as interface, type and type-only imports. They exist only at compile time.

  • Code outside <script setup>. In the Options API the template resolves names through the component instance, where a local variable of setup() or of the module scope is not visible, so the same ambiguity cannot arise. Duplicated names in the Options API are reported by vue/no-dupe-keys instead.

  • Props created by defineModel(). Such a prop is meant to be consumed through the ref that the macro returns, and naming that ref after the model (const foo = defineModel('foo')) is the idiomatic usage rather than a mistake.

🔧 Options ​

Nothing.

📚 Further Reading ​

🔍 Implementation ​