Skip to content

Latest commit

 

History

History
132 lines (93 loc) · 5.83 KB

File metadata and controls

132 lines (93 loc) · 5.83 KB

Vue.js et Nuxt

Statut : stable · Niveau : avancé

Conventions spécifiques à Alsacréations pour Vue.js et Nuxt. Les bonnes pratiques génériques (Composition API, réactivité, <script setup>, composants en PascalCase — voir Conventions de nommage —, v-for toujours accompagné de :key, favoriser les computed aux méthodes, extraire des composables pour éviter la duplication…) ne sont pas reprises ici : elles sont déjà appliquées par défaut. Ce document ne liste que ce qui distingue nos projets d'un projet Vue/Nuxt standard — à appliquer sans qu'il soit nécessaire de le redemander.


Outillage et dépendances imposées

Par défautVolar (vue.volar dans .vscode/extensions.json), et cette pile de dépendances plutôt que des alternatives équivalentes :

💡 Avant d'ajouter une dépendance (npm install), vérifier son poids avec pkg-size.dev ou l'inspecter avec node-modules.dev.

Organisation des composants

  • Sous-dossiers par usage (ui/, profile/, modals/…), pas par type technique.
  • Jamais d'attribut id sur un élément de composant : un composant réutilisé plusieurs fois sur une page dupliquerait l'id. Générer un id unique à l'exécution (ex. uuid) si un id est réellement nécessaire.
  • Styles écrits dans le fichier .vue du composant, avec l'attribut scoped par défaut : colocalisation JS/HTML/CSS, pas de code mort résiduel une fois le composant supprimé. Sous-découper le template en composants dès qu'il devient difficile à lire.

Template

  • v-if, v-for, v-show sont toujours les premières directives déclarées sur l'élément.
  • Espacer les expressions entre moustaches : {{ variable }}, jamais {{variable}}.
  • :key sur un v-for peut aussi servir à forcer le rafraîchissement d'un composant — pas seulement à satisfaire le linter.

Props

Toute prop a une valeur par défaut sauf si elle est requise. Les props booléennes sont préfixées is (isLoading, isReady). Préférer un objet complet à une liste de props éclatées :

<script setup lang="ts">
// ✅ un objet complet
defineProps<{ person: Person }>()

// ❌ trop verbeux — une prop par champ
defineProps({
  firstname: { type: String, required: true },
  lastname: { type: String, required: true },
})
</script>

Data

Regrouper les champs de formulaire liés (v-model) dans un seul objet reactive, envoyé tel quel à l'API plutôt que reconstruit :

const form = reactive({ email: '', productQty: 0 })

En développement avec données de remplissage, préfixer par TEMP pour qu'elles restent repérables dans le code.

Events

Définir les emits typés plutôt qu'un tableau de chaînes :

<script setup lang="ts">
defineEmits<{
  change: [param: string]
  update: [param: number]
}>()
</script>

Pour limiter la fréquence d'un événement, lodash.debounce plutôt qu'un debounce maison.

Composants globaux

Pour les composants utilisés très fréquemment (ex. Icon), enregistrement global plutôt qu'un import répété partout :

import { createApp } from 'vue'
import Icon from '@/components/global/Icon.vue'

const app = createApp({})
app.component('icon', Icon)

À réserver aux composants réellement transverses — l'import local reste la règle par défaut.

Internationalisation (i18n)

vue-i18n, fichiers de config par langue (i18n/fr-FR.js, i18n/en-US.js). Regrouper les clés par fonctionnalité (formulaires, actions communes…) d'abord, par nom de composant seulement si plus spécifique.

Contexte Syntaxe
Texte brut {{ $t('identSignin.createAccount') }}
Valeur de prop/attribut :placeholder="$t('formInput.lastname')"
Dans le <script> title: $t('result.title')
Condition sur la locale v-if="$i18n.locale == 'fr'"
Lien racine <nuxt-link :to="localePath('/')">
Nombres/prix $n(13.37, 'currency') ou $n(13.37, { currency: 'EUR' })

Pour des clés propres à un seul composant (texte de page unique), bloc <i18n> en fin de fichier plutôt que de faire grossir les fichiers de traduction communs — à utiliser avec modération :

<i18n>
{
  "fr": { "title": "Le titre", "description": "La description" }
}
</i18n>

Modales

Teleport vers body, via le composant maison <modal> (props name, variant, classname, title) plutôt qu'une modale ad hoc par cas d'usage :

<Teleport to="body">
  <modal v-if="isOpened" name="burger" variant="modal-simple" classname="modal-burger" title="Menu">
    <modal-burger />
  </modal>
</Teleport>

Voir aussi