Cours Vue.js · Module 6: Composants
Enregistrement et import des composants
Dans cette leçon4
Le Dr Nova explique : « Au NOVA LAB, chaque module d'habitat doit être officiellement enregistré dans le système de la station avant de pouvoir fonctionner. De même, les composants Vue doivent être importés ou enregistrés pour pouvoir être utilisés dans un template. »
Que se passe-t-il si tu écris <StatusBar /> dans un template sans dire à Vue où trouver ce composant ? Vue ne devinera pas le chemin du fichier. La console affiche l'avertissement « Failed to resolve component: StatusBar », et la page garde un élément vide que le navigateur ne connaît pas. L'enregistrement, c'est justement cette information : quel composant se cache derrière un nom donné.
L'import dans <script setup>
La méthode la plus courante et la plus recommandée est l'import local dans le bloc <script setup>. Un composant importé est automatiquement disponible dans le template - inutile de l'enregistrer où que ce soit ! Regarde un panneau de commande composé de trois modules :
1<!-- MissionControl.vue -->
2<template>
3 <div class="control-panel">
4 <ModuleCard />
5 <StatusBar />
6 <AlertPanel />
7 </div>
8</template>
9
10<script setup>
11// Il suffit d'importer - le composant est immédiatement disponible dans le template !
12import ModuleCard from './components/ModuleCard.vue'
13import StatusBar from './components/StatusBar.vue'
14import AlertPanel from './components/AlertPanel.vue'
15</script>Un fichier .vue expose son composant comme export par défaut, c'est pourquoi on l'importe sans accolades, et le nom donné à l'import devient le nom de la balise dans le template. Le chemin commence par ./, il est donc relatif. Tu pourrais tout aussi bien utiliser l'alias de la configuration de Vite : @/components/StatusBar.vue.
À noter : avec l'Options API (sans <script setup>), il faudrait en plus enregistrer les composants dans l'option components: {}. Avec la Composition API et <script setup>, cette étape est inutile - Vue reconnaît automatiquement les composants importés. Compare les deux écritures :
1<!-- Options API - enregistrement manuel requis -->
2<script>
3import ModuleCard from './components/ModuleCard.vue'
4
5export default {
6 components: {
7 ModuleCard // Enregistrement obligatoire !
8 }
9}
10</script>
11
12<!-- Composition API <script setup> - enregistrement automatique -->
13<script setup>
14import ModuleCard from './components/ModuleCard.vue'
15// Terminé ! Rien de plus à faire.
16</script>L'import est identique dans les deux versions - la différence tient à ce qui se passe après. Le compilateur de <script setup> remarque tout seul que ModuleCard est utilisé dans le template et le branche pour toi. Tu croiseras l'ancienne écriture dans la documentation et dans des projets existants, alors il vaut la peine de la reconnaître.
L'enregistrement global
Si un composant est utilisé à de nombreux endroits de l'application (par ex. un bouton, une icône), tu peux l'enregistrer globalement dans le fichier main.js, dans la même séquence d'allumage que tu as découverte dans la Launch Zone :
1// main.js
2import { createApp } from 'vue'
3import App from './App.vue'
4import BaseButton from './components/common/BaseButton.vue'
5import BaseIcon from './components/common/BaseIcon.vue'
6
7const app = createApp(App)
8
9// Enregistrement global - disponible partout sans import
10app.component('BaseButton', BaseButton)
11app.component('BaseIcon', BaseIcon)
12
13app.mount('#app')La méthode app.component() prend un nom et un composant, et ses appels se placent avant mount(), comme les appels à app.use(). Après l'enregistrement global, le composant est disponible dans chaque template sans avoir à l'importer :
1<!-- N'importe quel composant de l'application -->
2<template>
3 <BaseButton>Lancer le module</BaseButton>
4 <BaseIcon name="rocket" />
5</template>
6
7<script setup>
8// Pas besoin d'importer BaseButton ni BaseIcon !
9</script>Le template est le même qu'avec un import local - seule la ligne import a disparu. Mais ce confort a un prix, que montre le tableau.
Local ou global - quand choisir quoi ?
| Caractéristique | Import local | Enregistrement global |
|---|---|---|
| Disponibilité | Uniquement dans le composant qui importe | Partout dans l'application |
| Tree-shaking | Oui - les composants inutilisés sont retirés du build | Non - toujours dans le bundle |
| Lisibilité | Dépendances visibles dans <script setup> | Dépendances cachées |
| Usage | La plupart des composants | Composants de base très utilisés (Base*, App*) |
La documentation de Vue pointe deux inconvénients de l'enregistrement global : l'outil de build ne retirera pas un composant inutilisé du paquet, et dans une grande application il est plus difficile de retrouver d'où vient un composant. Traite donc l'import local comme la règle par défaut. N'enregistre globalement que les composants de base vraiment très utilisés - c'est ma recommandation pour toute la base.
PascalCase ou kebab-case dans le template
Vue accepte les deux conventions de nommage dans les templates. Un composant importé sous le nom ModuleCard peut aussi s'écrire module-card :
1<script setup>
2import ModuleCard from './ModuleCard.vue'
3import StatusBar from './StatusBar.vue'
4</script>
5
6<template>
7 <!-- PascalCase (recommandé dans les SFC) -->
8 <ModuleCard />
9 <StatusBar />
10
11 <!-- kebab-case (fonctionne aussi) -->
12 <module-card />
13 <status-bar />
14</template>Les deux écritures insèrent les mêmes composants. Le PascalCase est recommandé dans les Single File Components (.vue), car :
- Il est plus facile de distinguer les composants Vue des éléments HTML natifs
<ModuleCard />est un composant,<div>est du HTML- Meilleure lisibilité et cohérence avec le nom du fichier
L'exception concerne les templates écrits directement dans un fichier HTML : le navigateur y ignore la casse, il faut donc utiliser le kebab-case et une balise de fermeture complète. Dans les fichiers .vue, ce piège n'existe pas, et une balise auto-fermante <ModuleCard /> fonctionne sans problème.
Dans l'éditeur ci-dessous, App.vue importe trois composants : StatusPanel, ControlBar et InfoCard. Supprime l'un des imports et regarde sa partie du panneau disparaître de l'aperçu.
Retiens ceci : un composant est comme un module du registre de la station - l'import local l'inscrit pour un seul panneau, app.component() pour toute la base, alors ne recours à l'enregistrement global que lorsqu'un module travaille vraiment partout.
Code de cette leçon : App.vue
1<script setup>
2import StatusPanel from './StatusPanel.vue'
3import ControlBar from './ControlBar.vue'
4import InfoCard from './InfoCard.vue'
5
6// Dans <script setup>, les composants importés sont automatiquement enregistrés
7// Pas besoin de les ajouter à components: {} - Vue le fait pour nous !
8</script>
9
10<template>
11 <div class="registration-lab">
12 <div class="header">
13 <h1>Enregistrement des composants - NOVA LAB</h1>
14 <p class="subtitle">Import et auto-enregistrement dans script setup</p>
15 </div>
16
17 <div class="info-panel">
18 <h3>Importer des composants</h3>
19 <p>Dans <strong>script setup</strong>, il suffit d'importer le composant - Vue l'enregistre automatiquement</p>
20 <p>Chaque composant est un fichier <strong>.vue</strong> distinct avec son propre template, script et style</p>
21 </div>
22
23 <div class="components-grid">
24 <StatusPanel />
25 <ControlBar />
26 <InfoCard />
27 </div>
28
29 <div class="code-note">
30 <h3>Comment ça marche ?</h3>
31 <p>1. On crée le fichier du composant (par ex. StatusPanel.vue)</p>
32 <p>2. On l'importe : import StatusPanel from './StatusPanel.vue'</p>
33 <p>3. On l'utilise dans le template : <StatusPanel /></p>
34 <p>C'est tout ! Aucun enregistrement supplémentaire n'est nécessaire.</p>
35 </div>
36 </div>
37</template>
38
39<style scoped>
40.registration-lab {
41 background: linear-gradient(135deg, #0a0e27 0%, #1a1e3f 100%);
42 min-height: 100vh;
43 padding: 2rem;
44 color: #ffffff;
45 font-family: 'Courier New', monospace;
46}
47
48.header {
49 text-align: center;
50 margin-bottom: 2rem;
51 padding-bottom: 1rem;
52 border-bottom: 2px solid #00ff88;
53}
54
55.header h1 {
56 font-size: 2rem;
57 color: #00ff88;
58 text-shadow: 0 0 20px rgba(0, 255, 136, 0.5);
59 margin: 0;
60}
61
62.subtitle {
63 color: #00b4d8;
64 font-size: 1.1rem;
65 margin-top: 0.5rem;
66}
67
68.info-panel {
69 background: rgba(0, 180, 216, 0.1);
70 border: 2px solid #00b4d8;
71 border-radius: 10px;
72 padding: 1.5rem;
73 margin-bottom: 2rem;
74}
75
76.info-panel h3 {
77 color: #00b4d8;
78 margin-top: 0;
79}
80
81.info-panel strong {
82 color: #00ff88;
83}
84
85.components-grid {
86 display: grid;
87 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
88 gap: 1.5rem;
89 margin-bottom: 2rem;
90}
91
92.code-note {
93 background: rgba(0, 0, 0, 0.4);
94 border-left: 4px solid #00ff88;
95 padding: 1.5rem;
96 border-radius: 8px;
97}
98
99.code-note h3 {
100 color: #00ff88;
101 margin-top: 0;
102}
103
104.code-note p {
105 color: #00b4d8;
106 margin: 0.5rem 0;
107}
108</style>Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Comment importe-t-on un composant dans <script setup> ?
2. Comment utilise-t-on un composant importé dans le template ?
Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.
Tâches pratiques dans le jeu
- Éditeur de code
Importe MarsModule et utilise-le dans App.vue.
- Tri vertical
Range les étapes pour importer un composant dans script setup :