Aller au contenu

4 min de lecture

Vue 3 au quotidien, ce que j’utilise vraiment

Vue a beaucoup d’outils. Après plusieurs projets en production, voici la petite partie que j’utilise tous les jours, et pourquoi j’ai laissé le reste de côté.

, développeuse front-end

  • Vue
  • TypeScript
  • Front-end

Quand on apprend Vue, on a l’impression qu’il faut tout connaître : les deux API, les mixins, les directives personnalisées, les render functions, Pinia, les plugins. En pratique, sur les projets que je livre, j’utilise une partie assez réduite de tout ça. Elle tient dans cet article.

<script setup> et rien d’autre

Tous mes composants sont écrits en <script setup lang="ts">. Pas d’Options API, même dans un vieux projet qu’on reprend : je migre le composant que je touche, et je laisse les autres jusqu’à ce que je les touche.

La raison n’est pas la mode. C’est que le code se lit de haut en bas, que TypeScript comprend tout sans annotation, et qu’un composable s’appelle comme une fonction ordinaire. Un composant de cinquante lignes en <script setup> se comprend en une lecture.

Des props typées, pas des objets de configuration

ProjectCard.vue
<script setup lang="ts">
import type { Project } from '~/data/projects'

const props = defineProps<{
  project: Project
  compact?: boolean
}>()

const emit = defineEmits<{
  open: [slug: string]
}>()
</script>

Deux habitudes ici. D’abord, le type vient du modèle de données, pas d’une redéfinition locale : si Project change, le composant le sait. Ensuite, defineEmits avec des types nommés. L’éditeur complète l’événement et son argument, et une faute de frappe dans un @open devient une erreur à la compilation.

defineModel pour tout ce qui se saisit

Avant, un champ contrôlé demandait une prop modelValue, un événement update:modelValue et un computed pour relier les deux. Depuis defineModel, c’est une ligne :

PhoneField.vue
<script setup lang="ts">
const phone = defineModel<string>({ default: '' })
</script>

<template>
  <input v-model="phone" type="tel" inputmode="tel" autocomplete="tel">
</template>

Le composant parent fait <PhoneField v-model="form.phone" /> et tout circule. Je l’utilise pour chaque champ de formulaire, chaque interrupteur, chaque sélecteur.

Les composables, pour une seule raison

Un composable, chez moi, existe quand la même logique réactive apparaît dans deux composants. Pas avant. Les trois que j’emporte de projet en projet :

  • useMediaQuery('(min-width: 1024px)'), pour adapter un comportement, pas un style (le style, c’est le rôle du CSS).
  • useTheme(), qui lit et écrit la préférence clair ou sombre.
  • useScrub(el, offset), qui transforme la position de défilement d’un élément en une valeur entre 0 et 1, pour les animations liées au scroll.

Ils font chacun moins de trente lignes. Un composable de deux cents lignes est en général un composant qui s’ignore.

computed plutôt que watch

Chaque fois que je suis tentée d’écrire un watch pour recalculer une valeur, je vérifie si un computed ne suffit pas. Neuf fois sur dix, oui. Le computed dit ce qu’est la valeur ; le watch dit quand la recalculer, et c’est là que les bugs de synchronisation se cachent.

Je garde watch pour les effets de bord : appeler une API, écrire dans le stockage, lancer une animation.

Le state global, le plus tard possible

Pinia est très bien. Mais la plupart des données d’un écran appartiennent à cet écran. Je commence toujours par un ref local, je passe des props vers le bas et des événements vers le haut, et je ne crée un store que quand deux pages éloignées ont vraiment besoin de la même donnée vivante : la session de l’utilisateur, un panier, un brouillon qui doit survivre à la navigation.

Un projet avec un seul store de vingt lignes est souvent en meilleure santé qu’un projet avec douze stores.

Ce que je n’utilise presque jamais

  • Les mixins. Un composable fait la même chose en lisible.
  • provide et inject en dehors des bibliothèques de composants. Dans une application, c’est du state global qui ne dit pas son nom.
  • Les render functions. Utiles dans une bibliothèque, inutiles dans une page.
  • v-html avec du contenu qui ne vient pas de moi.

Le mot de la fin

Vue permet beaucoup de choses, et c’est tant mieux. Mais un projet qu’on peut reprendre six mois plus tard est un projet qui utilise peu de choses, toujours de la même façon. Ce que je décris ici tient sur une page, et c’est volontaire : c’est ce qu’un nouveau venu doit lire pour contribuer dès le premier jour.

Un projet, une question ?

Un projet, une question ? Écrivez-moi, je réponds sous 48 h.

contact@melaniedasilva.fr

À lire ensuite

    • IA
    • Méthode
    • Claude Code

    Coder avec une IA sans perdre la main

    J’utilise Claude Code tous les jours. Voici ce que je lui confie, ce que je garde, et les règles qui m’évitent de livrer du code que je ne comprends pas.

    4 min de lecture

    • IA
    • Interface
    • Accessibilité

    Ce qu’une IA ne voit pas dans une interface

    Une IA génère un écran correct en quelques secondes. Les détails qui le rendent agréable, ou simplement utilisable, viennent après. Liste de ce que je vérifie à la main.

    4 min de lecture