Vize

Règles de type et de script

Chaque règle présente sur cette page son objectif, sa configuration et ses exemples complets Mauvais et Bon, accompagnés de leurs explications. Les lignes surlignées montrent les modifications ; le code copié conserve la source complète. Les limites de prise en charge actuelles sont précisées avant les exemples concernés.

Règle Exemples Objectif
script/component-options-name-casing Mauvais · Bon Imposer PascalCase à l’option name du composant
script/custom-event-name-casing Mauvais · Bon Imposer camelCase aux noms des événements personnalisés émis
script/define-emits-declaration Mauvais · Bon Imposer la forme typée defineEmits<{}>() à la place de la forme à l’exécution sous forme de tableau
script/define-macros-order Mauvais · Bon Imposer un ordre cohérent aux macros du compilateur Vue dans <script setup>
script/define-props-declaration Mauvais · Bon Imposer la forme typée defineProps<{ ... }>() à la place de la forme à l’exécution sous forme d’objet
script/define-props-destructuring Mauvais · Bon Imposer un style cohérent de déstructuration de defineProps dans <script setup>
script/no-arrow-functions-in-watch Mauvais · Bon Interdire les fonctions fléchées comme gestionnaires watch de l’Options API
script/no-async-in-computed Mauvais · Bon Interdire les fonctions asynchrones dans les propriétés calculées
script/no-boolean-default Mauvais · Bon Interdire une valeur par défaut sur une prop Boolean
script/no-deep-destructure-in-props Mauvais · Bon Interdire la déstructuration profondément imbriquée dans defineProps
script/no-deprecated-data-object-declaration Mauvais · Bon Interdire un objet littéral comme option data du composant (Vue 3 exige une fonction)
script/no-deprecated-destroyed-lifecycle Mauvais · Bon Interdire les hooks de cycle de vie dépréciés destroyed et beforeDestroy
script/no-deprecated-dollar-listeners-api Mauvais · Bon Interdire la propriété d’instance $listeners supprimée dans Vue 3 (fusionnée dans $attrs)
script/no-deprecated-dollar-scopedslots-api Mauvais · Bon Interdire la propriété d’instance $scopedSlots supprimée dans Vue 3 (utiliser $slots)
script/no-deprecated-events-api Mauvais · Bon Interdire l’API d’événements de Vue 2 supprimée ($on / $off / $once)
script/no-deprecated-props-default-this Mauvais · Bon Interdire this dans une fonction de valeur par défaut ou de validation de prop (supprimé dans Vue 3)
script/no-dupe-keys Mauvais · Bon Interdire les clés dupliquées entre props/data/computed/methods/setup/inject de l’Options API
script/no-duplicate-attr-inheritance Mauvais · Bon Signaler un composant qui applique deux fois ses attributs transmis automatiquement
script/no-export-in-script-setup Mauvais · Bon Interdire les instructions export dans <script setup>
script/no-expose-after-await Mauvais · Bon Interdire expose() et defineExpose() après un await
script/no-get-current-instance Mauvais · Bon Interdire getCurrentInstance() en mode Vapor (renvoie null)
script/no-import-compiler-macros Mauvais · Bon Interdire l’import des macros du compilateur Vue importées automatiquement
script/no-internal-imports Mauvais · Bon Interdire les imports depuis les modules internes de Vue
script/no-lifecycle-after-await Mauvais · Bon Interdire l’enregistrement de hooks de cycle de vie après un await dans setup()
script/no-multiple-slot-args Mauvais · Bon Interdire de passer plusieurs arguments à un appel de fonction de slot à portée
script/no-next-tick Mauvais · Bon Interdire l’utilisation de nextTick() dans les composants destinés à Vapor
script/no-options-api Mauvais · Bon Interdire les formes de l’Options API en mode Vapor
script/no-potential-component-option-typo Mauvais · Bon Signaler les fautes de frappe probables dans les noms d’options de composant de l’Options API
script/no-reactive-destructure Mauvais · Bon Interdire la déstructuration d’objets réactifs qui fait perdre la réactivité
script/no-ref-as-operand Mauvais · Bon Exiger l’accès via .value aux variables liées à une ref lorsqu’elles servent d’opérande
script/no-required-prop-with-default Mauvais · Bon Interdire une prop qui possède à la fois required: true et une valeur par défaut
script/no-reserved-identifiers Mauvais · Bon Interdire les identifiants réservés du compilateur Vue
script/no-reserved-keys Mauvais · Bon Interdire les noms réservés par Vue comme clés de props/data/computed/methods/setup/inject de l’Options API
script/no-reserved-props Mauvais · Bon Interdire les noms réservés dans la déclaration des props d’un composant
script/no-restricted-globals Mauvais · Bon Interdire les références aux variables globales de l’environnement d’exécution qui doivent passer par une couche d’encapsulation typée
script/no-restricted-members Mauvais · Bon Interdire les accès aux membres object.property configurés par le projet
script/no-side-effects-in-computed-properties Mauvais · Bon Interdire les effets de bord dans les getters calculés de l’Options API
script/no-top-level-ref-in-script Mauvais · Bon Interdire ref/reactive au niveau supérieur pour éviter la contamination de l’état entre requêtes
script/no-unstable-nested-components Mauvais · Bon Interdire les définitions de composants dans les fonctions setup ou de rendu
script/no-unused-emit-declarations Mauvais · Bon Signaler les événements déclarés qui ne sont jamais émis
script/no-use-computed-property-like-method Mauvais · Bon Interdire d’appeler une propriété calculée de l’Options API comme une méthode
script/no-watch-after-await Mauvais · Bon Interdire les observateurs créés après un await dans setup() sans conserver leur fonction d’arrêt
script/no-with-defaults Mauvais · Bon Déconseiller withDefaults au profit des valeurs par défaut dans la déstructuration (Vue 3.5+)
script/prefer-computed Mauvais · Bon Préférer computed() pour l’état réactif dérivé
script/prefer-define-options Mauvais · Bon Préférer defineOptions() à un <script> ordinaire qui ne définit que name/inheritAttrs
script/prefer-import-from-vue Mauvais · Bon Préférer les imports depuis 'vue' plutôt que depuis les packages internes
script/prefer-ref-over-reactive Mauvais · Bon Recommander ref() plutôt que reactive() pour gérer l’état
script/prefer-use-attrs Mauvais · Bon Recommander useAttrs() plutôt que context.attrs
script/prefer-use-id Mauvais · Bon Recommander useId() pour générer des identifiants uniques (Vue 3.5+)
script/prefer-use-slots Mauvais · Bon Recommander useSlots() plutôt que context.slots
script/prefer-use-template-ref Mauvais · Bon Recommander useTemplateRef plutôt que ref pour les références de template (Vue 3.5+)
script/require-default-prop Mauvais · Bon Exiger une valeur par défaut pour chaque prop facultative non booléenne
script/require-explicit-emits Mauvais · Bon Exiger la déclaration des événements émis dans defineEmits ou l’option emits
script/require-explicit-slots Mauvais · Bon Exiger que les slots utilisés via useSlots() soient explicitement typés avec defineSlots<...>()
script/require-function-return-type Mauvais · Bon Exiger des annotations de type de retour sur les fonctions
script/require-prop-type-constructor Mauvais · Bon Exiger que les valeurs type des props soient des constructeurs plutôt que des chaînes littérales
script/require-prop-types Mauvais · Bon Exiger que chaque prop déclare un type
script/require-symbol-provide Mauvais · Bon Recommander Symbol comme clé d’injection pour provide/inject
script/require-typed-object-prop Mauvais · Bon Exiger un type explicite sur une prop dont le type à l’exécution est Object ou Array
script/require-typed-ref Mauvais · Bon Exiger un argument de type explicite sur un ref() initialisé sans valeur, avec null ou avec undefined
script/require-valid-default-prop Mauvais · Bon Exiger que la valeur par défaut d’une prop soit valide pour son type déclaré
script/return-in-computed-property Mauvais · Bon Exiger une valeur de retour dans chaque getter calculé
script/return-in-emits-validator Mauvais · Bon Exiger une valeur de retour dans chaque validateur emits de l’Options API
script/valid-define-emits Mauvais · Bon Imposer une utilisation valide de defineEmits() (pas d’arguments de type et d’exécution combinés, pas de références locales, un seul appel)
script/valid-define-options Mauvais · Bon Imposer une utilisation valide de defineOptions() (un seul argument objet, sans props/emits/expose/slots)
script/valid-define-props Mauvais · Bon Imposer une utilisation valide de defineProps() (un seul appel, pas d’arguments de type et d’exécution combinés, pas de références locales)
script/valid-next-tick Mauvais · Bon Exiger que le résultat d’un appel nextTick() soit attendu, chaîné ou associé à un callback
type/no-floating-promises Mauvais · Bon Interdire les Promises laissées sans traitement
type/no-reactivity-loss Mauvais · Bon Interdire les instantanés ordinaires de valeurs réactives lors des affectations et des appels
type/no-unsafe-template-binding Mauvais · Bon Interdire les liaisons de template dont le type résolu est non sûr
type/require-typed-emits Mauvais · Bon Exiger une définition de type pour defineEmits
type/require-typed-props Mauvais · Bon Exiger une définition de type pour defineProps
type/strict-boolean-expressions Mauvais · Bon Exiger des expressions booléennes sûres dans les conditions des scripts et des templates

Toutes les règles · Options des règles · Correspondance de migration ESLint · Vérifications du projet · Attributs entre composants

script/component-options-name-casing

Imposer PascalCase à l’option name du composant

Mauvais · Bon

Gravité par défaut: error
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/component-options-name-casing": "error"
      }
    },
  },
});
vp run lint

Mauvais

L’option de composant name: 'my-component' utilise kebab-case, alors que cette règle exige un nom de composant littéral en PascalCase.

<script lang="ts">
export default {
  name: 'my-component' // kebab-case
}
</script>

Bon

MyComponent commence par une majuscule et ne contient que des caractères alphanumériques, ce qui satisfait le contrôle du nom.

<script lang="ts">
export default {
  name: 'MyComponent'
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/custom-event-name-casing

Imposer camelCase aux noms des événements personnalisés émis

Mauvais · Bon

Gravité par défaut: error
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Consultez les options typées et leurs valeurs par défaut.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/custom-event-name-casing": "error"
      }
    },
  },
});
vp run lint

Mauvais

La chaîne émise my-event contient un tiret et enfreint la convention camelCase par défaut pour les noms d’événements.

<script setup lang="ts">
const emit = defineEmits(['my-event'])
emit('my-event')         // kebab-case → report
</script>

Bon

La déclaration et l’appel utilisent tous deux myEvent, ce qui maintient la correspondance entre le nom de l’événement et son émission tout en respectant la convention de casse par défaut. Une convention kebab-case configurée impose une autre forme.

<script setup lang="ts">
const emit = defineEmits(['myEvent'])
emit('myEvent')
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/define-emits-declaration

Imposer la forme typée defineEmits<{}>() à la place de la forme à l’exécution sous forme de tableau

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/define-emits-declaration": "warn"
      }
    },
  },
});
vp run lint

Mauvais

defineEmits(["change"]) utilise une déclaration par tableau à l’exécution ; cette règle de style préfère une déclaration typée.

<script setup lang="ts">
const emit = defineEmits(["change"]);
emit("change", 1);
</script>

Bon

defineEmits<{ change: [id: number] }>() place la déclaration de l’événement dans un argument de type et décrit explicitement la charge utile numérique utilisée par emit("change", 1).

<script setup lang="ts">
const emit = defineEmits<{ change: [id: number] }>();
emit("change", 1);
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/define-macros-order

Imposer un ordre cohérent aux macros du compilateur Vue dans <script setup>

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Consultez les options typées et leurs valeurs par défaut.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/define-macros-order": "warn"
      }
    },
  },
});
vp run lint

Mauvais

defineEmits apparaît avant defineProps, alors que defineProps puis defineEmits doivent être les premières instructions de <script setup>.

<script setup lang="ts">
// defineEmits before defineProps
const emit = defineEmits<{ change: [value: string] }>()
const props = defineProps<{ count: number }>()
</script>

Bon

defineProps puis defineEmits suivent directement les imports, avant toute autre instruction ; les autres macros peuvent suivre dans n’importe quel ordre.

<script setup lang="ts">
import { ref } from 'vue'
const props = defineProps<{ count: number }>()
const emit = defineEmits<{ change: [value: string] }>()
const model = defineModel<string>()
const value = ref(0)
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/define-props-declaration

Imposer la forme typée defineProps<{ ... }>() à la place de la forme à l’exécution sous forme d’objet

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/define-props-declaration": "warn"
      }
    },
  },
});
vp run lint

Mauvais

defineProps({ title: String }) fournit un objet à l’exécution, ce qui va à l’encontre de la préférence de cette règle pour les props typées.

<script setup lang="ts">
const props = defineProps({ title: String });
console.log(props.title);
</script>

Bon

defineProps<{ title: string }>() déclare title dans l’argument de type et conserve l’accès props.title sans argument de déclaration à l’exécution.

<script setup lang="ts">
const props = defineProps<{ title: string }>();
console.log(props.title);
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/define-props-destructuring

Imposer un style cohérent de déstructuration de defineProps dans <script setup>

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Consultez les options typées et leurs valeurs par défaut.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/define-props-destructuring": "warn"
      }
    },
  },
});
vp run lint

Mauvais

defineProps est affecté à la seule liaison props au lieu d’être déstructuré, contrairement à la préférence par défaut pour la déstructuration.

<script setup lang="ts">
const props = defineProps<{ foo: string }>()
</script>

Bon

Le motif objet lie directement foo et bar et donne une valeur par défaut à bar, qui est facultatif. Cela repose sur la déstructuration réactive des props de Vue 3.5+ ; le mode configurable never préfère la forme opposée.

<script setup lang="ts">
const { foo, bar = 'default' } = defineProps<{ foo: string; bar?: string }>()
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-arrow-functions-in-watch

Interdire les fonctions fléchées comme gestionnaires watch de l’Options API

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-arrow-functions-in-watch": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le watcher value de l’Options API et le gestionnaire imbriqué other.handler sont des fonctions fléchées. Une fonction fléchée capture le this du contexte environnant au lieu de recevoir l’instance du composant.

<script lang="ts">
export default {
  watch: {
    // `this` is not the component instance inside an arrow function.
    value: () => {
      this.doSomething()
    },
    other: {
      handler: () => {}
    }
  }
}
</script>

Bon

Les deux gestionnaires deviennent des méthodes ordinaires, ce qui permet à Vue de lier this au composant. L’option du watcher deep: true reste compatible avec la forme objet.

<script lang="ts">
export default {
  watch: {
    value(newValue, oldValue) {
      this.doSomething()
    },
    other: {
      handler(newValue) {},
      deep: true
    }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-async-in-computed

Interdire les fonctions asynchrones dans les propriétés calculées

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-async-in-computed": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le getter computed est async : la récupération produit donc une Promise au lieu d’une valeur calculée dérivée de manière synchrone.

<script setup lang="ts">
import { computed } from "vue";
const data = computed(async () => {
  const response = await fetch("/api/data");
  return response.json();
});
</script>

Bon

La récupération asynchrone est déplacée dans watch, qui stocke son résultat dans data.value. Le nettoyage annule l’ancienne requête et empêche un callback inactif d’écrire un résultat périmé ; aucun getter calculé asynchrone ne subsiste.

<script setup lang="ts">
import { ref, watch } from "vue";
const query = ref("");
const data = ref<unknown>(null);
watch(query, async (value, _oldValue, onCleanup) => {
  const controller = new AbortController();
  let active = true;
  onCleanup(() => { active = false; controller.abort(); });
  const response = await fetch(`/api/data?q=${encodeURIComponent(value)}`, { signal: controller.signal });
  const next: unknown = await response.json();
  if (active) data.value = next;
});
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-boolean-default

Interdire une valeur par défaut sur une prop Boolean

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-boolean-default": "warn"
      }
    },
  },
});
vp run lint

Mauvais

disabled et checked déclarent tous deux un default sur une prop dont le seul constructeur est Boolean ; la règle rejette même une valeur par défaut explicite false.

<script lang="ts">
export default {
  props: {
    // Boolean props already default to false; an explicit default is confusing.
    disabled: { type: Boolean, default: true },
    checked: { type: Boolean, default: false }
  }
}
</script>

Bon

Les props exclusivement booléennes omettent default et utilisent la valeur false implicite de Vue. L’union [Boolean, String] et la prop Number montrent que ce contrôle se limite au constructeur Boolean employé seul.

<script lang="ts">
export default {
  props: {
    // No explicit default: defaults to false.
    disabled: { type: Boolean },
    disabled2: Boolean,
    // Union type may legitimately need a default.
    value: { type: [Boolean, String], default: '' },
    // Non-Boolean prop.
    count: { type: Number, default: 0 }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-deep-destructure-in-props

Interdire la déstructuration profondément imbriquée dans defineProps

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deep-destructure-in-props": "warn"
      }
    },
  },
});
vp run lint

Mauvais

Le motif de liaison descend dans user pour déstructurer name, dépassant la profondeur limitée de déstructuration des props autorisée par défaut.

<script setup lang="ts">
const { user: { name } } = defineProps<{ user: { name: string } }>();
</script>

Bon

L’objet des props reste intact, et un getter calculé lit props.user.name. L’accès imbriqué reste explicite sans motif de liaison profondément imbriqué.

<script setup lang="ts">
import { computed } from "vue";
const props = defineProps<{ user: { name: string } }>();
const userName = computed(() => props.user.name);
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-deprecated-data-object-declaration

Interdire un objet littéral comme option data du composant (Vue 3 exige une fonction)

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-data-object-declaration": "error"
      }
    },
  },
});
vp run lint

Mauvais

L’option data de l’Options API est un objet littéral, une forme de Vue 2 que Vue 3 n’accepte plus.

<script lang="ts">
export default {
  // `data` must be a function in Vue 3, not an object literal.
  data: {
    count: 0
  }
}
</script>

Bon

data() renvoie un nouvel objet { count: 0 }, fournissant la déclaration de données par fonction exigée par Vue 3.

<script lang="ts">
export default {
  data() {
    return { count: 0 }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-deprecated-destroyed-lifecycle

Interdire les hooks de cycle de vie dépréciés destroyed et beforeDestroy

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Disponible pour les diagnostics pris en charge
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-destroyed-lifecycle": "error"
      }
    },
  },
});
vp run lint

Mauvais

beforeDestroy est l’option de cycle de vie de Vue 2 supprimée, utilisée ici pour nettoyer le minuteur.

<script lang="ts">
export default { beforeDestroy() { clearTimeout(this.timer); } };
</script>

Bon

Renommer le hook en beforeUnmount conserve le corps du nettoyage sous son nom de cycle de vie Vue 3.

<script lang="ts">
export default { beforeUnmount() { clearTimeout(this.timer); } };
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-deprecated-dollar-listeners-api

Interdire la propriété d’instance $listeners supprimée dans Vue 3 (fusionnée dans $attrs)

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-dollar-listeners-api": "error"
      }
    },
  },
});
vp run lint

Mauvais

Les accès aux membres et la référence passée directement en argument utilisent tous $listeners, que Vue 3 a supprimé après avoir fusionné les écouteurs dans les attributs.

<script>
export default {
  mounted() {
    const vm = this
    return vm.$listeners
  }
}
</script>
<template><Child v-on="$listeners" /></template>

Bon

Les accès passent à this.$attrs et à ctx.attrs dans le contexte setup. Ils remplacent l’API supprimée des écouteurs ; les objets récepteurs illustrés doivent exister dans le contexte environnant du composant.

<script>
export default {
  mounted() {
    return this.$attrs
  }
}
</script>
<template><Child v-bind="$attrs" /></template>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-deprecated-dollar-scopedslots-api

Interdire la propriété d’instance $scopedSlots supprimée dans Vue 3 (utiliser $slots)

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-dollar-scopedslots-api": "error"
      }
    },
  },
});
vp run lint

Mauvais

this.$scopedSlots, ctx.$scopedSlots et la référence directe $scopedSlots utilisent l’API des slots à portée de Vue 2, supprimée dans Vue 3.

<script setup lang="ts">
const header = this.$scopedSlots.header
const footer = ctx.$scopedSlots.footer
render($scopedSlots.default)
</script>

Bon

Remplacer $scopedSlots par $slots utilise l’API unifiée des slots. L’exemple supprime l’écriture dépréciée sans établir un contexte setup pour les objets récepteurs.

<script setup lang="ts">
const header = this.$slots.header
const footer = ctx.$slots.footer
render($slots.default)
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-deprecated-events-api

Interdire l’API d’événements de Vue 2 supprimée ($on / $off / $once)

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-events-api": "error"
      }
    },
  },
});
vp run lint

Mauvais

Les appels $on, $once et $off utilisent les méthodes de bus d’événements de l’instance supprimées dans Vue 3.

<script>
export default {
  mounted() {
    this.$on('event', handler)
    const vm = this
    vm.$once('event', handler)
    this.$off('event', handler)
  }
}
</script>

Bon

$emit reste valide, tandis que l’abonnement au bus d’événements passe à la méthode on de l’émetteur externe. La correction sépare l’émission destinée au parent du bus d’événements externe.

<script>
import mitt from 'mitt'
const emitter = mitt()
export default {
  mounted() {
    this.$emit('event', payload)
    emitter.on('event', handler)
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-deprecated-props-default-this

Interdire this dans une fonction de valeur par défaut ou de validation de prop (supprimé dans Vue 3)

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-props-default-this": "error"
      }
    },
  },
});
vp run lint

Mauvais

La valeur par défaut et le validateur de la prop lisent this, mais ces fonctions ne peuvent pas s’appuyer sur l’instance du composant dans Vue 3.

<script lang="ts">
export default {
  props: {
    size: {
      type: Number,
      // `this` is not the component instance in Vue 3.
      default() {
        return this.defaultSize
      }
    },
    value: {
      type: Number,
      validator() {
        return this.value > 0
      }
    }
  }
}
</script>

Bon

La fonction de valeur par défaut lit props.baseSize dans son argument, et le validateur teste son argument value. Tous deux cessent de dépendre d’un récepteur d’instance indisponible.

<script lang="ts">
export default {
  props: {
    size: {
      type: Number,
      // Vue 3 passes the raw props as the first argument instead.
      default(props) {
        return props.baseSize
      }
    },
    value: {
      type: Number,
      validator(value) {
        return value > 0
      }
    }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-dupe-keys

Interdire les clés dupliquées entre props/data/computed/methods/setup/inject de l’Options API

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-dupe-keys": "error"
      }
    },
  },
});
vp run lint

Mauvais

foo est déclaré à la fois dans props et data, et bar à la fois dans computed et methods. Ces déclarations se disputent les mêmes clés de l’instance du composant.

<script lang="ts">
export default {
  props: ['foo'],
  data() {
    return { foo: 1 } // duplicate of prop `foo`
  },
  computed: {
    bar() { return 2 }
  },
  methods: {
    bar() {} // duplicate of computed `bar`
  }
}
</script>

Bon

Les déclarations de prop, de données et de propriété calculée utilisent des noms distincts (foo, bar et baz), éliminant les deux collisions entre options.

<script lang="ts">
export default {
  props: ['foo'],
  data() {
    return { bar: 1 }
  },
  computed: {
    baz() { return 2 }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-duplicate-attr-inheritance

Signaler un composant qui applique deux fois ses attributs transmis automatiquement

Mauvais · Bon

Gravité par défaut: warning
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-duplicate-attr-inheritance": "warn"
      }
    },
  },
});
vp run lint

Mauvais

Les valeurs explicites inheritAttrs: true répètent le comportement par défaut de Vue. Cette règle signale ce littéral redondant même si aucun déploiement de $attrs sur la racine n’est montré.

<script setup></script>
<template><div><button v-bind="$attrs">Save</button></div></template>

Bon

inheritAttrs: false exprime une véritable désactivation, tandis que l’objet d’options vide laisse l’héritage par défaut implicite. Aucun ne répète la valeur redondante true.

<script setup>defineOptions({ inheritAttrs: false })</script>
<template><div><button v-bind="$attrs">Save</button></div></template>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-export-in-script-setup

Interdire les instructions export dans <script setup>

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-export-in-script-setup": "error"
      }
    },
  },
});
vp run lint

Mauvais

export const count tente d’exposer un export de module depuis <script setup>, où les exports à l’exécution sont interdits.

<script setup lang="ts">
export const count = 1;
</script>

Bon

Supprimer export conserve count comme liaison setup plutôt que comme export de module.

<script setup lang="ts">
const count = 1;
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-expose-after-await

Interdire expose() et defineExpose() après un await

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-expose-after-await": "error"
      }
    },
  },
});
vp run lint

Mauvais

defineExpose() s’exécute après un await de premier niveau, alors qu’aucune instance de composant n’est courante ; rien n’est donc exposé.

<script setup lang="ts">
await loadData()
defineExpose({ reload })
</script>

Bon

defineExpose() s’exécute avant le premier await, tant que l’instance du composant est courante.

<script setup lang="ts">
defineExpose({ reload })
await loadData()
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-get-current-instance

Interdire getCurrentInstance() en mode Vapor (renvoie null)

Mauvais · Bon

Gravité par défaut: error
Préréglages: opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Contrôles de script destinés à Vapor ; une activation explicite applique aussi la restriction aux scripts ordinaires
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-get-current-instance": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le setup marqué Vapor importe et appelle getCurrentInstance, s’appuyant sur une API d’instance que cette règle interdit pour les composants destinés à Vapor.

<script setup lang="ts" vapor>
import { getCurrentInstance } from "vue";
const instance = getCurrentInstance();
</script>

Bon

inject("app-config") obtient la configuration explicitement fournie sans importer ni appeler getCurrentInstance.

<script setup lang="ts" vapor>
import { inject } from "vue";
const appConfig = inject("app-config");
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-import-compiler-macros

Interdire l’import des macros du compilateur Vue importées automatiquement

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-import-compiler-macros": "error"
      }
    },
  },
});
vp run lint

Mauvais

L’import depuis vue inclut defineProps et defineEmits, alors que ces macros du compilateur sont directement disponibles dans <script setup>.

<script setup lang="ts">
import { defineProps, defineEmits } from "vue";
const props = defineProps<{ title: string }>();
const emit = defineEmits<{ save: [id: number] }>();
</script>

Bon

Supprimer les imports des macros conserve les deux appels typés ; aucune déclaration ne nécessite d’import à l’exécution.

<script setup lang="ts">
const props = defineProps<{ title: string }>();
const emit = defineEmits<{ save: [id: number] }>();
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-internal-imports

Interdire les imports depuis les modules internes de Vue

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-internal-imports": "error"
      }
    },
  },
});
vp run lint

Mauvais

Les deux imports ciblent des fichiers internes dist plutôt que le point d’entrée public du package Vue, couplant le composant aux chemins des fichiers de build.

<script setup lang="ts">
import { foo } from '@vue/runtime-core/dist/runtime-core.esm-bundler'
import { bar } from 'vue/dist/vue.esm-bundler'
</script>

Bon

Importer les utilitaires nécessaires depuis vue supprime la dépendance aux emplacements des fichiers de distribution internes.

<script setup lang="ts">
import { ref, computed } from 'vue'
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-lifecycle-after-await

Interdire l’enregistrement de hooks de cycle de vie après un await dans setup()

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-lifecycle-after-await": "error"
      }
    },
  },
});
vp run lint

Mauvais

setup() appelle onMounted() après await loadData() ; sans instance de composant courante à ce moment, le hook n’est jamais enregistré.

<script lang="ts">
import { onMounted } from 'vue'
export default {
  async setup() {
    await loadData()
    onMounted(() => {})
  },
}
</script>

Bon

onMounted() est enregistré avant le premier await, tant que setup() s’exécute de manière synchrone pour le composant.

<script lang="ts">
import { onMounted } from 'vue'
export default {
  async setup() {
    onMounted(() => {})
    await loadData()
  },
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-multiple-slot-args

Interdire de passer plusieurs arguments à un appel de fonction de slot à portée

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-multiple-slot-args": "warn"
      }
    },
  },
});
vp run lint

Mauvais

Les appels de slots passent plusieurs arguments positionnels ou déploient une liste d’arguments inconnue. Les slots Vue reçoivent un seul objet de props, et non une liste de paramètres positionnels.

<script setup lang="ts">
slots.default(foo, bar)
$slots.header(a, b)
this.$scopedSlots.item(x, y)
useSlots().default(a, b)
slots.default(...args)
</script>

Bon

{ foo, bar } regroupe les données dans un seul argument ; slotProps et l’appel sans argument respectent également la forme d’appel de slot prise en charge.

<script setup lang="ts">
slots.default({ foo, bar })
slots.default(slotProps)
slots.default()
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-next-tick

Interdire l’utilisation de nextTick() dans les composants destinés à Vapor

Mauvais · Bon

Gravité par défaut: error
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Contrôles de script destinés à Vapor ; une activation explicite applique aussi la restriction aux scripts ordinaires
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-next-tick": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le composant destiné à Vapor importe nextTick et attend son résultat, introduisant la dépendance à la planification des mises à jour du DOM que cette règle de migration rejette.

<script setup lang="ts" vapor>
import { nextTick } from "vue";
await nextTick();
</script>

Bon

L’input est obtenu par useTemplateRef et reçoit le focus dans onMounted. Ce point de montage explicite remplace la dépendance de l’exemple à nextTick.

<script setup lang="ts" vapor>
import { onMounted, useTemplateRef } from "vue";
const input = useTemplateRef<HTMLInputElement>("input");
onMounted(() => { input.value?.focus(); });
</script>
<template><input ref="input"></template>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-options-api

Interdire les formes de l’Options API en mode Vapor

Mauvais · Bon

Gravité par défaut: error
Préréglages: opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Contrôles de script destinés à Vapor ; une activation explicite applique aussi la restriction aux scripts ordinaires
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-options-api": "error"
      }
    },
  },
});
vp run lint

Mauvais

L’objet exporté par défaut déclare data() de l’Options API, une forme d’option de composant interdite par cette règle.

<script lang="ts">
export default {
  data() {
    return { count: 0 };
  },
};
</script>

Bon

L’état du composant devient une ref de la Composition API dans le <script setup> Vapor, supprimant l’objet de l’Options API et son option data.

<script setup lang="ts" vapor>
const count = ref(0);
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-potential-component-option-typo

Signaler les fautes de frappe probables dans les noms d’options de composant de l’Options API

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-potential-component-option-typo": "error"
      }
    },
  },
});
vp run lint

Mauvais

L’option est écrite method, à une modification près de l’option reconnue methods ; Vue ne la traiterait pas comme la déclaration de méthodes souhaitée.

<script lang="ts">
export default { method: { save() {} } };
</script>

Bon

Changer la clé en methods place save() sous l’option de composant reconnue.

<script lang="ts">
export default { methods: { save() {} } };
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-reactive-destructure

Interdire la déstructuration d’objets réactifs qui fait perdre la réactivité

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-reactive-destructure": "warn"
      }
    },
  },
});
vp run lint

Mauvais

const { count, name } = state copie les propriétés primitives hors de l’objet reactive, perdant leur lien avec les modifications ultérieures des propriétés.

<script setup lang="ts">
import { reactive } from "vue";
const state = reactive({ count: 0, name: "Ada" });
const { count, name } = state;
</script>

Bon

Déstructurer toRefs(state) crée des refs pour count et name, en maintenant chaque liaison reliée à la propriété réactive d’origine.

<script setup lang="ts">
import { reactive, toRefs } from "vue";
const state = reactive({ count: 0, name: "Ada" });
const { count, name } = toRefs(state);
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-ref-as-operand

Exiger l’accès via .value aux variables liées à une ref lorsqu’elles servent d’opérande

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-ref-as-operand": "error"
      }
    },
  },
});
vp run lint

Mauvais

count + 1 utilise l’objet ref lui-même comme opérande arithmétique au lieu du nombre qu’il contient.

<script setup lang="ts">
import { ref } from "vue";
const count = ref(0);
const next = count + 1;
</script>

Bon

count.value + 1 lit le nombre contenu avant d’ajouter un ; l’arithmétique dans le script exige cet accès explicite à la ref.

<script setup lang="ts">
import { ref } from "vue";
const count = ref(0);
const next = count.value + 1;
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-required-prop-with-default

Interdire une prop qui possède à la fois required: true et une valeur par défaut

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-required-prop-with-default": "error"
      }
    },
  },
});
vp run lint

Mauvais

title est à la fois obligatoire et doté de la valeur de repli "Untitled", combinant un contrat d’entrée obligatoire avec une valeur par défaut prévue pour une entrée manquante.

<script lang="ts">
export default { props: { title: { type: String, required: true, default: "Untitled" } } };
</script>

Bon

Supprimer required: true rend title facultatif et conserve "Untitled" comme valeur de repli cohérente.

<script lang="ts">
export default { props: { title: { type: String, default: "Untitled" } } };
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-reserved-identifiers

Interdire les identifiants réservés du compilateur Vue

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-reserved-identifiers": "error"
      }
    },
  },
});
vp run lint

Mauvais

Les liaisons __props, __emit et __sfc__ utilisent des identifiants réservés au code généré par le compilateur Vue.

<script setup lang="ts">
const __props = { name: "Ada" };
const __emit = () => {};
const __sfc__ = {};
</script>

Bon

Les noms ordinaires props, emit et componentData évitent ces identifiants générés tout en conservant les déclarations de props et d’événements émis.

<script setup lang="ts">
const props = defineProps<{ name: string }>();
const emit = defineEmits<{ save: [] }>();
const componentData = {};
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-reserved-keys

Interdire les noms réservés par Vue comme clés de props/data/computed/methods/setup/inject de l’Options API

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-reserved-keys": "error"
      }
    },
  },
});
vp run lint

Mauvais

La clé de données renvoyée $el entre en conflit avec une propriété intégrée de l’instance du composant Vue et utilise également le préfixe réservé $.

<script lang="ts">
export default { data() { return { $el: "custom" }; } };
</script>

Bon

Renommer les données de l’application en elementLabel évite l’API intégrée de l’instance et le préfixe réservé.

<script lang="ts">
export default { data() { return { elementLabel: "custom" }; } };
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-reserved-props

Interdire les noms réservés dans la déclaration des props d’un composant

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-reserved-props": "error"
      }
    },
  },
});
vp run lint

Mauvais

ref et $foo dans la forme objet, ainsi que key dans la forme tableau, sont des noms de props réservés. ref et key sont des mécanismes du framework, et les noms préfixés par $ sont rejetés.

<script lang="ts">
export default {
  props: {
    ref: String,   // reserved
    $foo: Number    // `$`-prefixed names are reserved
  }
}

export default {
  props: ['key']    // reserved (array form)
}
</script>

Bon

Les noms de props ordinaires name et refValue évitent les noms réservés tant par leur graphie que par leur préfixe.

<script lang="ts">
export default {
  props: {
    name: String,
    refValue: Number
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-restricted-globals

Interdire les références aux variables globales de l’environnement d’exécution qui doivent passer par une couche d’encapsulation typée

Mauvais · Bon

Gravité par défaut: error
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Consultez les options typées et leurs valeurs par défaut.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-restricted-globals": "error"
      }
    },
  },
});
vp run lint

Mauvais

L’exemple lit directement les variables globales restreintes par défaut process, localStorage et sessionStorage, en contournant les utilitaires explicites de configuration et de stockage du projet.

<script setup lang="ts">
const flag = process.env.FEATURE_FLAG
const token = localStorage.getItem('auth.token')
sessionStorage.setItem('view.scroll', String(window.scrollY))
</script>

Bon

useFeatureFlag, authStorage.read et viewStorage.write suppriment ces références directes aux variables globales restreintes. L’accès restant à window.scrollY ne fait pas partie des restrictions par défaut de cette règle ; la sécurité SSR est une question distincte.

<script setup lang="ts">
// Use a typed config helper that distinguishes server vs. client.
const flag = useFeatureFlag('FEATURE_FLAG')

// Use a typed wrapper that scopes keys and handles SSR / disabled storage.
const token = authStorage.read('auth.token')
viewStorage.write('view.scroll', String(window.scrollY))
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-restricted-members

Interdire les accès aux membres object.property configurés par le projet

Mauvais · Bon

Gravité par défaut: error
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Consultez les options typées et leurs valeurs par défaut.

Cet exemple configure window.localStorage. La règle n’a aucune liste d’interdiction par défaut ; son activation seule ne signale pas de membre.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-restricted-members": "error"
      },
      "ruleOptions": {
        "script/no-restricted-members": {
          "members": [
            {
              "object": "window",
              "property": "localStorage"
            }
          ]
        }
      }
    },
  },
});
vp run lint

Mauvais

Lorsque { object: "window", property: "localStorage" } est configuré dans ruleOptions, window.localStorage accède à la paire objet/membre interdite. Cette règle n’interdit aucun membre par défaut.

<script setup lang="ts">
const token = window.localStorage.getItem("token");
</script>

Bon

authStorage.read("token") délègue la lecture à l’utilitaire de stockage de l’application et n’accède plus au membre configuré window.localStorage.

<script setup lang="ts">
const token = authStorage.read("token");
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-side-effects-in-computed-properties

Interdire les effets de bord dans les getters calculés de l’Options API

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-side-effects-in-computed-properties": "error"
      }
    },
  },
});
vp run lint

Mauvais

doubled affecte une valeur à this.count, et reversed modifie this.items par reverse(). Les deux getters modifient l’état dont ils sont censés dériver leur valeur.

<script lang="ts">
export default {
  data() {
    return { count: 0, items: [] }
  },
  computed: {
    doubled() {
      this.count = this.count * 2 // side effect: assigns to data
      return this.count
    },
    reversed() {
      return this.items.reverse() // side effect: mutates the array
    }
  }
}
</script>

Bon

doubled renvoie le résultat de la multiplication sans affectation. reversed copie le tableau avant de l’inverser, de sorte que le getter ne modifie pas l’état d’origine du composant.

<script lang="ts">
export default {
  data() {
    return { count: 0, items: [] }
  },
  computed: {
    doubled() {
      return this.count * 2
    },
    reversed() {
      return [...this.items].reverse() // operate on a copy
    }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-top-level-ref-in-script

Interdire ref/reactive au niveau supérieur pour éviter la contamination de l’état entre requêtes

Mauvais · Bon

Gravité par défaut: error
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-top-level-ref-in-script": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le <script> ordinaire initialise count et user dans la portée du module. Pendant le SSR, ces objets d’état peuvent être partagés entre les instances du composant et les requêtes.

<script>
// This state is shared across all requests in SSR!
const count = ref(0)
const user = reactive({ name: '' })

export default {
  setup() {
    return { count, user }
  }
}
</script>

Bon

La ref de setup est initialisée pour chaque instance du composant ; le script ordinaire ne conserve qu’une constante, une fonction produisant de l’état et une ref créée dans setup(). Aucun ne crée d’état réactif dans la portée du module ordinaire.

<script setup>
// Script setup creates fresh state per request
const count = ref(0)
</script>

<script>
// Constants are fine
const API_URL = 'https://api.example.com'

// Functions that create state are fine
function createState() {
  return reactive({ count: 0 })
}

export default {
  setup() {
    // Create state inside setup
    const count = ref(0)
    return { count }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-unstable-nested-components

Interdire les définitions de composants dans les fonctions setup ou de rendu

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-unstable-nested-components": "warn"
      }
    },
  },
});
vp run lint

Mauvais

defineComponent s’exécute dans le setup() du parent et crée une nouvelle définition du composant Child chaque fois que ce setup s’exécute.

<script lang="ts">
import { defineComponent } from "vue";
export default { setup() { const Child = defineComponent({ render() { return null; } }); return { Child }; } };
</script>

Bon

La définition de Child passe dans la portée du module, et setup() renvoie cette définition existante au lieu de la recréer.

<script lang="ts">
import { defineComponent } from "vue";
const Child = defineComponent({ render() { return null; } });
export default { setup() { return { Child }; } };
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-unused-emit-declarations

Signaler les événements déclarés qui ne sont jamais émis

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-unused-emit-declarations": "warn"
      }
    },
  },
});
vp run lint

Mauvais

defineEmits déclare à la fois change et unused, mais la fonction emit récupérée n’émet que l’événement littéral change.

<script setup lang="ts">
const emit = defineEmits(['change', 'unused'])
emit('change')
// `unused` is never emitted
</script>

Bon

Supprimer unused fait correspondre la liste des événements déclarés à l’émission observée. L’exemple utilise une liaison emit récupérée et non transmise à l’extérieur, ce qui permet cette conclusion sur son utilisation locale.

<script setup lang="ts">
const emit = defineEmits(['change'])
emit('change')
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-use-computed-property-like-method

Interdire d’appeler une propriété calculée de l’Options API comme une méthode

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-use-computed-property-like-method": "error"
      }
    },
  },
});
vp run lint

Mauvais

this.total() appelle la valeur exposée par le getter calculé ; ce getter renvoie 3, qui ne peut pas être appelé.

<script lang="ts">
export default { computed: { total() { return 3; } }, methods: { log() { console.log(this.total()); } } };
</script>

Bon

this.total lit la valeur calculée sans parenthèses d’appel, de sorte que log affiche le nombre dérivé.

<script lang="ts">
export default { computed: { total() { return 3; } }, methods: { log() { console.log(this.total); } } };
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-watch-after-await

Interdire les observateurs créés après un await dans setup() sans conserver leur fonction d’arrêt

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-watch-after-await": "error"
      }
    },
  },
});
vp run lint

Mauvais

watch() est créé après await loadData() et sa fonction d’arrêt est ignorée ; l’observateur n’est donc jamais arrêté avec le composant.

<script lang="ts">
import { watch } from 'vue'
export default {
  async setup(props) {
    await loadData()
    watch(() => props.id, reload)
  },
}
</script>

Bon

L’observateur est créé avant le premier await, donc Vue l’arrête lorsque le composant est démonté.

<script lang="ts">
import { watch } from 'vue'
export default {
  async setup(props) {
    watch(() => props.id, reload)
    await loadData()
  },
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/no-with-defaults

Déconseiller withDefaults au profit des valeurs par défaut dans la déstructuration (Vue 3.5+)

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-with-defaults": "warn"
      }
    },
  },
});
vp run lint

Mauvais

withDefaults enveloppe la déclaration typée des props uniquement pour fournir les valeurs par défaut de count et name, au lieu du style de valeurs par défaut dans la déstructuration de Vue 3.5+ préféré ici.

<script setup lang="ts">
const props = withDefaults(defineProps<{ count?: number; name?: string }>(), { count: 0, name: "Ada" });
</script>

Bon

Le motif de déstructuration place count = 0 et name = "Ada" à côté de leurs liaisons et supprime l’enveloppe withDefaults.

<script setup lang="ts">
const { count = 0, name = "Ada" } = defineProps<{ count?: number; name?: string }>();
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/prefer-computed

Préférer computed() pour l’état réactif dérivé

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Le watcher doit uniquement dériver la destination. Les copies modifiables et les callbacks ayant d’autres effets de bord sont autorisés.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-computed": "warn"
      }
    },
  },
});
vp run lint

Mauvais

Le watcher ne fait que copier une valeur dérivée de count dans une seconde ref, doubled ; l’état dérivé est donc maintenu par synchronisation manuelle.

<script setup lang="ts">
import { ref, watch } from "vue";
const count = ref(0);
const doubled = ref(0);
watch(count, (value) => { doubled.value = value * 2; });
</script>

Bon

computed(() => count.value * 2) exprime directement la dérivation et supprime à la fois la ref modifiable supplémentaire et le watcher qui la synchronise.

<script setup lang="ts">
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/prefer-define-options

Préférer defineOptions() à un <script> ordinaire qui ne définit que name/inheritAttrs

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-define-options": "warn"
      }
    },
  },
});
vp run lint

Mauvais

La seule instruction significative du script ordinaire exporte un objet contenant uniquement name et inheritAttrs ; ces options peuvent être exprimées par defineOptions.

<script lang="ts">
export default { name: 'MyComponent', inheritAttrs: false }
</script>

Bon

La méthode data() montrée donne au script une véritable logique de l’Options API ; il échappe donc à la suggestion prudente de cette règle, limitée aux options seules. Cet exemple Bon démontre une exception autorisée ; la migration directe placerait defineOptions({ name: 'MyComponent', inheritAttrs: false }) dans <script setup>.

<script lang="ts">
// Real options logic — keep the plain script.
export default {
  name: 'MyComponent',
  data() { return { count: 0 } },
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/prefer-import-from-vue

Préférer les imports depuis 'vue' plutôt que depuis les packages internes

Mauvais · Bon

Gravité par défaut: warning
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Disponible pour les diagnostics pris en charge
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-import-from-vue": "warn"
      }
    },
  },
});
vp run lint

Mauvais

ref et h sont importés depuis les packages internes @vue/runtime-core et @vue/runtime-dom plutôt que depuis le package public vue.

<script setup lang="ts">
import { ref } from '@vue/runtime-core'
import { h } from '@vue/runtime-dom'
</script>

Bon

Les utilitaires publics sont importés depuis vue. Le privé isString conserve @vue/shared, car vue ne l’exporte pas. Les imports de namespace, par défaut et mixtes publics/privés gardent un avertissement sans correction automatique.

<script setup lang="ts">
import { ref, h } from 'vue'
import { isString } from '@vue/shared'
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/prefer-ref-over-reactive

Recommander ref() plutôt que reactive() pour gérer l’état

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-ref-over-reactive": "warn"
      }
    },
  },
});
vp run lint

Mauvais

L’état est créé avec reactive, contrairement à la préférence de cette règle de convention pour les refs. L’exemple illustre une préférence de style ; il ne s’agit pas d’un objet réactif intrinsèquement invalide.

<script setup lang="ts">
// reactive requires careful handling to avoid losing reactivity
const state = reactive({
  count: 0,
  name: 'foo'
})
</script>

Bon

Les exemples créent aussi bien l’état scalaire que l’état objet avec ref ; les champs liés peuvent également être répartis dans des refs distinctes. Cela respecte la forme de création d’état préférée.

<script setup lang="ts">
// ref is more explicit and safer
const count = ref(0)
const name = ref('foo')

// For objects, ref still works
const user = ref({ name: 'foo', age: 20 })

// Or use multiple refs for related data
const userName = ref('foo')
const userAge = ref(20)
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/prefer-use-attrs

Recommander useAttrs() plutôt que context.attrs

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-use-attrs": "warn"
      }
    },
  },
});
vp run lint

Mauvais

setup obtient attrs en déstructurant son paramètre de contexte, ce que cette règle demande de remplacer par l’utilitaire de la Composition API.

<script lang="ts">
export default { setup(_props, { attrs }) { console.log(attrs.class); } };
</script>

Bon

useAttrs() fournit attrs dans setup, en conservant la lecture de attrs.class sans dépendre du second paramètre de setup.

<script lang="ts">
import { useAttrs } from "vue";
export default { setup() { const attrs = useAttrs(); console.log(attrs.class); } };
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/prefer-use-id

Recommander useId() pour générer des identifiants uniques (Vue 3.5+)

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-use-id": "warn"
      }
    },
  },
});
vp run lint

Mauvais

id contient Math.random() : l’identifiant généré pour l’input et le label peut donc différer entre les rendus serveur et client. Sa liaison dont le nom désigne un ID est le contexte de génération reconnu par la règle.

<script setup lang="ts">
const id = `input-${Math.random()}`;
</script>
<template><label :for="id">Name</label><input :id="id" /></template>

Bon

useId() de Vue 3.5+ génère l’identifiant, et :for comme :id continuent de lire la même liaison au lieu de générer indépendamment des valeurs aléatoires.

<script setup lang="ts">
import { useId } from "vue";
const id = useId();
</script>
<template><label :for="id">Name</label><input :id="id" /></template>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/prefer-use-slots

Recommander useSlots() plutôt que context.slots

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-use-slots": "warn"
      }
    },
  },
});
vp run lint

Mauvais

setup déstructure slots depuis son argument de contexte, la forme d’accès que cette règle préfère remplacer.

<script lang="ts">
import { defineComponent, h } from "vue";
export default defineComponent({
  setup(_props, { slots }) { return () => h("div", slots.default?.()); },
});
</script>

Bon

useSlots() récupère les slots dans setup, en conservant la fonction de rendu et son appel facultatif au slot par défaut sans paramètre de contexte.

<script lang="ts">
import { defineComponent, h, useSlots } from "vue";
export default defineComponent({
  setup() {
    const slots = useSlots();
    return () => h("div", slots.default?.());
  },
});
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/prefer-use-template-ref

Recommander useTemplateRef plutôt que ref pour les références de template (Vue 3.5+)

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-use-template-ref": "warn"
      }
    },
  },
});
vp run lint

Mauvais

La ref nullable input est associée au littéral ref="input" du template, ce qui l’identifie comme une référence d’élément plutôt que comme une donnée nullable ordinaire.

<script setup lang="ts">
import { ref } from 'vue'
const input = ref<HTMLInputElement | null>(null)
</script>
<template>
  <input ref="input" />
</template>

Bon

useTemplateRef<HTMLInputElement>('input') de Vue 3.5+ rend cette référence de template explicite. error = ref(null), sans association, reste une donnée ordinaire et est volontairement hors du champ de cette règle.

<script setup lang="ts">
import { ref, useTemplateRef } from 'vue'
// Paired with the template ref below.
const input = useTemplateRef<HTMLInputElement>('input')
// A nullable data ref the template never binds as a ref.
const error = ref(null)
</script>
<template>
  <input ref="input" />
  <p>{{ error }}</p>
</template>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-default-prop

Exiger une valeur par défaut pour chaque prop facultative non booléenne

Mauvais · Bon

Gravité par défaut: error
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-default-prop": "error"
      }
    },
  },
});
vp run lint

Mauvais

name et age sont des props à l’exécution facultatives, non booléennes et sans valeur par défaut ; leurs valeurs en cas d’omission restent indéterminées.

<script lang="ts">
export default {
  props: {
    // optional, non-Boolean, no default
    name: String,
    age: { type: Number },
  }
}
</script>

Bon

name reçoit default: ''. enabled utilise la valeur false implicite de Boolean, et id, obligatoire, n’a pas besoin de valeur de repli, ce qui illustre les deux exemptions.

<script lang="ts">
export default {
  props: {
    name: { type: String, default: '' },
    enabled: Boolean,                 // Boolean defaults to false
    id: { type: Number, required: true },
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-explicit-emits

Exiger la déclaration des événements émis dans defineEmits ou l’option emits

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-explicit-emits": "warn"
      }
    },
  },
});
vp run lint

Mauvais

La fonction emit récupérée émet save, mais defineEmits([]) ne déclare pas cet événement.

<script setup lang="ts">
const emit = defineEmits([]);
emit("save");
</script>

Bon

Ajouter "save" à la déclaration intègre l’événement littéral émis au contrat explicite d’événements du composant.

<script setup lang="ts">
const emit = defineEmits(["save"]);
emit("save");
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-explicit-slots

Exiger que les slots utilisés via useSlots() soient explicitement typés avec defineSlots<...>()

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-explicit-slots": "warn"
      }
    },
  },
});
vp run lint

Mauvais

La déclaration typée defineProps<{ id: number }>() établit une syntaxe TypeScript, mais setup utilise useSlots() sans déclaration defineSlots. La règle détecte donc des slots utilisés sans contrat de slots explicite.

<script setup lang="ts">
const props = defineProps<{ id: number }>()
const slots = useSlots()
</script>

Bon

defineSlots déclare un slot default dont les props incluent msg: string ; useSlots() apparaît désormais aux côtés d’un contrat de slots explicitement typé.

<script setup lang="ts">
defineSlots<{ default(props: { msg: string }): unknown }>()
const slots = useSlots()
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-function-return-type

Exiger des annotations de type de retour sur les fonctions

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-function-return-type": "warn"
      }
    },
  },
});
vp run lint

Mauvais

add et greet annotent tous deux leurs paramètres mais omettent une annotation de type de retour ; les retours inférés ne satisfont pas cette convention d’annotation explicite.

<script setup lang="ts">
const add = (a: number, b: number) => {
  return a + b
}

function greet(name: string) {
  return `Hello, ${name}`
}
</script>

Bon

add déclare : number, et greet déclare : string, rendant leurs contrats de retour explicites sans changer leurs corps.

<script setup lang="ts">
const add = (a: number, b: number): number => {
  return a + b
}

function greet(name: string): string {
  return `Hello, ${name}`
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-prop-type-constructor

Exiger que les valeurs type des props soient des constructeurs plutôt que des chaînes littérales

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-prop-type-constructor": "error"
      }
    },
  },
});
vp run lint

Mauvais

Les déclarations de props utilisent les chaînes "String" et "Number" comme types à l’exécution, y compris dans le tableau de constructeurs. Ces chaînes ne sont pas des fonctions constructeurs.

<script lang="ts">
export default {
  props: {
    // The type should be the `String` constructor, not the string "String".
    name: "String",
    age: { type: "Number" },
    id: { type: ["String", "Number"] }
  }
}
</script>

Bon

Les déclarations utilisent les véritables identifiants String et Number, y compris dans le tableau d’union [String, Number].

<script lang="ts">
export default {
  props: {
    name: String,
    age: { type: Number },
    id: { type: [String, Number] }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-prop-types

Exiger que chaque prop déclare un type

Mauvais · Bon

Gravité par défaut: error
Préréglages: opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-prop-types": "error"
      }
    },
  },
});
vp run lint

Mauvais

L’entrée du tableau ne déclare que le nom status ; la valeur null et le descripteur vide ne déclarent pas non plus de type de prop à l’exécution.

<script lang="ts">
export default {
  props: ['status']            // array form: no types
}

export default {
  props: {
    status: null,              // no type
    other: {}                  // empty descriptor: no type
  }
}
</script>

Bon

status: String fournit un constructeur sous forme abrégée, et other fournit type: Number dans son descripteur. Les deux props possèdent désormais des déclarations de type.

<script lang="ts">
export default {
  props: {
    status: String,
    other: { type: Number, default: 0 }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-symbol-provide

Recommander Symbol comme clé d’injection pour provide/inject

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-symbol-provide": "warn"
      }
    },
  },
});
vp run lint

Mauvais

provide et inject utilisent des clés sous forme de chaînes littérales telles que 'user' et 'theme', qui peuvent entrer en conflit avec un autre fournisseur utilisant la même graphie.

<script setup lang="ts">
// String keys can collide
provide('user', user)
const user = inject('user')

// Magic strings are error-prone
provide('theme', { dark: true })
</script>

Bon

La clé partagée UserKey est créée avec Symbol et annotée comme InjectionKey<User> ; les deux appels passent cette clé au lieu d’une chaîne littérale.

<script lang="ts">
// Define injection key with Symbol
export const UserKey: InjectionKey<User> = Symbol('user')

// Provide with Symbol
provide(UserKey, user)

// Inject with Symbol
const user = inject(UserKey)
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-typed-object-prop

Exiger un type explicite sur une prop dont le type à l’exécution est Object ou Array

Mauvais · Bon

Gravité par défaut: warning
Préréglages: opinionated, nuxt
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-typed-object-prop": "warn"
      }
    },
  },
});
vp run lint

Mauvais

Les constructeurs Object et Array employés seuls ne décrivent que des catégories générales à l’exécution ; ni user ni la structure des éléments de items n’a donc de type statique explicite.

<script setup lang="ts">
const props = defineProps({ user: Object, items: { type: Array } });
</script>

Bon

PropType<User> et PropType<User[]> ajoutent les types de l’objet et des éléments tout en conservant les mêmes constructeurs à l’exécution.

<script setup lang="ts">
import type { PropType } from "vue";
interface User { name: string }
const props = defineProps({
  user: Object as PropType<User>,
  items: { type: Array as PropType<User[]> },
});
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-typed-ref

Exiger un argument de type explicite sur un ref() initialisé sans valeur, avec null ou avec undefined

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-typed-ref": "warn"
      }
    },
  },
});
vp run lint

Mauvais

Les appels à ref importé n’ont ni argument de type ni valeur initiale utile : l’absence d’argument, null et undefined ne permettent pas d’inférer le type de valeur futur souhaité.

<script setup lang="ts">
import { ref } from 'vue'

const a = ref()           // Ref<undefined>
const b = ref(null)       // Ref<null>
const c = ref(undefined)  // Ref<undefined>
</script>

Bon

Des arguments de type explicites décrivent les refs de chaîne et de User nullable. ref(0) possède déjà une valeur initiale numérique concrète et peut s’appuyer sur l’inférence.

<script setup lang="ts">
import { ref } from 'vue'

const a = ref<string>()
const b = ref<User | null>(null)
const c = ref(0)          // inferred Ref<number>
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/require-valid-default-prop

Exiger que la valeur par défaut d’une prop soit valide pour son type déclaré

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-valid-default-prop": "error"
      }
    },
  },
});
vp run lint

Mauvais

Les props Number et Boolean reçoivent des valeurs scalaires par défaut incompatibles, et les props Array et Object utilisent des valeurs littérales partagées au lieu de fonctions de création.

<script lang="ts">
export default {
  props: {
    count: { type: Number, default: '0' },     // string default for Number
    enabled: { type: Boolean, default: 1 },     // non-boolean default for Boolean
    items: { type: Array, default: [] },        // literal must be a factory
    config: { type: Object, default: {} }       // literal must be a factory
  }
}
</script>

Bon

Les valeurs scalaires par défaut deviennent 0 et false ; les valeurs par défaut du tableau et de l’objet deviennent des fonctions renvoyant de nouvelles valeurs. L’exemple [String, Number] accepte sa valeur par défaut de type chaîne, car elle correspond à l’un des types déclarés.

<script lang="ts">
export default {
  props: {
    count: { type: Number, default: 0 },
    enabled: { type: Boolean, default: false },
    items: { type: Array, default: () => [] },
    config: { type: Object, default: () => ({}) },
    label: { type: [String, Number], default: '' }
  }
}
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/return-in-computed-property

Exiger une valeur de retour dans chaque getter calculé

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/return-in-computed-property": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le getter calculé dont le corps est un bloc évalue 1 + 2 mais ne le renvoie jamais, laissant la valeur calculée à undefined.

<script setup lang="ts">
import { computed } from "vue";
const total = computed(() => { 1 + 2; });
</script>

Bon

return 1 + 2 transforme l’expression en valeur renvoyée par le getter. La règle recherche un return renvoyant une valeur dans le getter lui-même, et non une simple instruction d’expression.

<script setup lang="ts">
import { computed } from "vue";
const total = computed(() => { return 1 + 2; });
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/return-in-emits-validator

Exiger une valeur de retour dans chaque validateur emits de l’Options API

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Utilisez une fonction fléchée à corps de bloc pour le filtre SFC actuellement pris en charge. Le validateur sous-jacent gère aussi la syntaxe abrégée des méthodes, mais le préfiltre SFC actuel ne transmet pas cette forme de façon fiable.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/return-in-emits-validator": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le validateur submit journalise la charge utile mais ne renvoie aucun résultat de validation ; son corps de bloc produit donc undefined.

<script lang="ts">
export default { emits: { submit: (payload: unknown) => { console.log(payload); } } };
</script>

Bon

return payload != null fournit un résultat de validation booléen pour la charge utile soumise au lieu de se terminer sans valeur de retour.

<script lang="ts">
export default { emits: { submit: (payload: unknown) => { return payload != null; } } };
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/valid-define-emits

Imposer une utilisation valide de defineEmits() (pas d’arguments de type et d’exécution combinés, pas de références locales, un seul appel)

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/valid-define-emits": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le même appel defineEmits fournit à la fois un argument de type et le tableau à l’exécution ["save"], mélangeant deux déclarations mutuellement exclusives.

<script setup lang="ts">
defineEmits<{ save: [] }>(["save"]);
</script>

Bon

Supprimer l’argument d’exécution laisse une seule déclaration d’événement typée pour save.

<script setup lang="ts">
defineEmits<{ save: [] }>();
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/valid-define-options

Imposer une utilisation valide de defineOptions() (un seul argument objet, sans props/emits/expose/slots)

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/valid-define-options": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le premier appel place la déclaration dédiée props dans defineOptions ; les appels suivants répètent également la macro et incluent un argument qui n’est pas un objet. Ils illustrent les contraintes sur les formes interdites et les appels répétés.

<script setup lang="ts">
defineOptions({ props: ['foo'] })   // use defineProps instead
defineOptions({ name: 'Foo' })
defineOptions({ name: 'Bar' })      // duplicate call
defineOptions('Foo')                // not an object literal
</script>

Bon

Un seul appel defineOptions reçoit un objet contenant uniquement les options ordinaires prises en charge name et inheritAttrs.

<script setup lang="ts">
defineOptions({ name: 'Foo', inheritAttrs: false })
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/valid-define-props

Imposer une utilisation valide de defineProps() (un seul appel, pas d’arguments de type et d’exécution combinés, pas de références locales)

Mauvais · Bon

Gravité par défaut: error
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/valid-define-props": "error"
      }
    },
  },
});
vp run lint

Mauvais

Le même appel defineProps fournit à la fois { title: string } comme argument de type et { title: String } comme argument d’exécution, ce que le compilateur n’autorise pas conjointement.

<script setup lang="ts">
defineProps<{ title: string }>({ title: String });
</script>

Bon

Supprimer l’objet d’exécution laisse une déclaration typée unique pour title au lieu de combiner les deux formes de déclaration.

<script setup lang="ts">
defineProps<{ title: string }>();
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

script/valid-next-tick

Exiger que le résultat d’un appel nextTick() soit attendu, chaîné ou associé à un callback

Mauvais · Bon

Gravité par défaut: warning
Préréglages: essential, happy-path, ecosystem, nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Scripts JS/TS des SFC Vue ; les exemples montrent la forme concernée de l’Options API ou de script setup
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/valid-next-tick": "warn"
      }
    },
  },
});
vp run lint

Mauvais

L’appel à nextTick() importé est une expression seule sans callback ; la Promise renvoyée est donc ignorée et aucun traitement n’attend l’application des mises à jour du DOM.

<script setup lang="ts">
import { nextTick } from "vue";
nextTick();
</script>

Bon

await nextTick() consomme la Promise et attend explicitement la prochaine mise à jour du DOM avant que le code setup suivant ne continue.

<script setup lang="ts">
import { nextTick } from "vue";
await nextTick();
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

type/no-floating-promises

Interdire les Promises laissées sans traitement

Mauvais · Bon

Gravité par défaut: warning
Préréglages: nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Informations de type dans les scripts et templates des SFC Vue, pour les constructions présentées ci-dessous
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Les contrôles utilisant les types s’appuient sur le runtime natif Corsa et le projet TypeScript. typeAware seul n’active pas une règle nécessitant une activation explicite.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/no-floating-promises": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

Mauvais

La fonction asynchrone save renvoie une Promise, mais l’appel isolé save() ne l’attend ni ne la renvoie, et ne marque pas explicitement son abandon volontaire.

<script setup lang="ts">
async function save(): Promise<void> {}
save();
</script>

Bon

void save() marque explicitement l’intention de lancer l’opération sans attendre son résultat, acceptée par cette règle. Il s’agit d’un marqueur explicite d’abandon, et non d’un gestionnaire de rejet.

<script setup lang="ts">
async function save(): Promise<void> {}
void save();
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

type/no-reactivity-loss

Interdire les instantanés ordinaires de valeurs réactives lors des affectations et des appels

Mauvais · Bon

Gravité par défaut: warning
Préréglages: nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Informations de type dans les scripts et templates des SFC Vue, pour les constructions présentées ci-dessous
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Les contrôles utilisant les types s’appuient sur le runtime natif Corsa et le projet TypeScript. typeAware seul n’active pas une règle nécessitant une activation explicite.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/no-reactivity-loss": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

Mauvais

const count = state.count prend un simple instantané numérique de la propriété réactive ; les mises à jour ultérieures de state.count ne sont donc pas répercutées dans cette liaison.

<script setup lang="ts">
import { reactive } from "vue";
const state = reactive({ count: 0 });
const count = state.count;
</script>

Bon

toRef(state, "count") maintient count relié à la propriété réactive d’origine plutôt que de copier sa valeur primitive actuelle.

<script setup lang="ts">
import { reactive, toRef } from "vue";
const state = reactive({ count: 0 });
const count = toRef(state, "count");
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

type/no-unsafe-template-binding

Interdire les liaisons de template dont le type résolu est non sûr

Mauvais · Bon

Gravité par défaut: warning
Préréglages: nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Informations de type dans les scripts et templates des SFC Vue, pour les constructions présentées ci-dessous
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Les contrôles utilisant les types s’appuient sur le runtime natif Corsa et le projet TypeScript. typeAware seul n’active pas une règle nécessitant une activation explicite.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/no-unsafe-template-binding": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

Mauvais

La valeur interpolée value est explicitement typée comme any ; le vérificateur ne peut donc pas attribuer à la liaison du template un type concret sûr.

<script setup lang="ts">
const value: any = "Hello";
</script>
<template><p>{{ value }}</p></template>

Bon

Changer l’annotation en string donne à la même interpolation un type concret vérifiable sans changer la valeur affichée.

<script setup lang="ts">
const value: string = "Hello";
</script>
<template><p>{{ value }}</p></template>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

type/require-typed-emits

Exiger une définition de type pour defineEmits

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Informations de type dans les scripts et templates des SFC Vue, pour les constructions présentées ci-dessous
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Les contrôles utilisant les types s’appuient sur le runtime natif Corsa et le projet TypeScript. typeAware seul n’active pas une règle nécessitant une activation explicite.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/require-typed-emits": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

Mauvais

La déclaration uniquement sous forme de tableau defineEmits(["save"]) déclare le nom de l’événement sans contrat typé pour ses arguments.

<script setup lang="ts">
defineEmits(["save"]);
</script>

Bon

defineEmits<{ save: [] }>() déclare l’événement typé save avec un tuple d’arguments vide, indiquant explicitement qu’il n’accepte aucun argument.

<script setup lang="ts">
defineEmits<{ save: [] }>();
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

type/require-typed-props

Exiger une définition de type pour defineProps

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Informations de type dans les scripts et templates des SFC Vue, pour les constructions présentées ci-dessous
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Les contrôles utilisant les types s’appuient sur le runtime natif Corsa et le projet TypeScript. typeAware seul n’active pas une règle nécessitant une activation explicite.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/require-typed-props": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

Mauvais

La déclaration uniquement sous forme de tableau defineProps(["title"]) déclare title par son nom sans lui donner de type.

<script setup lang="ts">
defineProps(["title"]);
</script>

Bon

defineProps<{ title: string }>() donne à title un type chaîne explicite au lieu d’une déclaration à l’exécution limitée à son nom.

<script setup lang="ts">
defineProps<{ title: string }>();
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

type/strict-boolean-expressions

Exiger des expressions booléennes sûres dans les conditions des scripts et des templates

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Informations de type dans les scripts et templates des SFC Vue, pour les constructions présentées ci-dessous
Options: Consultez les options typées et leurs valeurs par défaut.

Activez explicitement typeAware et cette règle. Par défaut, les nombres pouvant être nuls sont interdits, tandis que les nombres non nuls sont autorisés.

Les contrôles utilisant les types s’appuient sur le runtime natif Corsa et le projet TypeScript. typeAware seul n’active pas une règle nécessitant une activation explicite.

Configuration (Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/strict-boolean-expressions": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

Mauvais

if (count) repose sur la conversion implicite en booléen d’une liaison numérique nullable plutôt que sur un test booléen explicite ; cela confond aussi zéro avec l’absence de valeur.

<script setup lang="ts">
const count: number | undefined = undefined;
if (count) console.log(count);
</script>

Bon

count !== undefined && count > 0 teste séparément la présence et la positivité, produisant une condition booléenne explicite après avoir affiné le type de la valeur optionnelle.

<script setup lang="ts">
const count: number | undefined = undefined;
if (count !== undefined && count > 0) console.log(count);
</script>

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles