Inscription globale des composants
Dans Vue 2, l'inscription d'un composant au niveau global s'effectue via Vue.component(), rendant le composant disponible dans toutes les instances de Vue créées par la suite.
const MonComposant = {
template: '<div>Disponible partout</div>'
};
Vue.component('mon-composant', MonComposant);
new Vue({ el: '#app1' });
new Vue({ el: '#app2' }); // Peut aussi utiliser mon-composant
En revanche, avec Vue 3, l’approche est modulaire. L’inscription se fait sur une application spécifique instnaciée via createApp. Ce changement implique que les composants inscrits ne sont accessibles que dans cette instance et ses enfants.
const app = Vue.createApp({
data() {
return { message: 'Application 1' };
}
});
app.component('mon-composant', {
template: '<div>Local à cette app</div>'
});
app.mount('#app');
// Une deuxième application ne pourra pas utiliser 'mon-composant'
const app2 = Vue.createApp({}).mount('#app2');
Inscription locale
Les deux versions supportent l’inscription locale via la propriété components dans les options du composant ou de l’instance racine. Un tel composant n’est accessible que dans le contexte où il est déclaré.
const composantInterne = {
template: '<p>Visible uniquement ici</p>'
};
// Vue 2
new Vue({
el: '#app',
components: {
'composant-interne': composantInterne
}
});
// Vue 3
Vue.createApp({
components: {
'composant-interne': composantInterne
}
}).mount('#app');
Gestion des composants dynamiques
La balise spéciale <component> permet de basculer entre plusieurs composants en utilisant l’attribut :is. La valeur liée peut changer selon l’état de l’application.
<button @click="changerComposant">Basculer</button>
<component :is="composantActif"></component>
Exemple d’implémentation :
const ComposantA = { template: '<input placeholder="Saisie A" />' };
const ComposantB = { template: '<input placeholder="Saisie B" />' };
Vue.createApp({
data() {
return {
index: 0,
composants: ['composant-a', 'composant-b'],
composantActif: 'composant-a'
};
},
methods: {
changerComposant() {
this.index = (this.index + 1) % 2;
this.composantActif = this.composants[this.index];
}
},
components: { 'composant-a': ComposantA, 'composant-b': ComposantB }
}).mount('#app');
Mémorisation des états avec <keep-alive>
Par défaut, lors d’un changement de composant, son état interne est perdu. Pour préserver l’état (par exemple, contenu d’un champ texte), on peut envelopper <component> dans <keep-alive>.
<keep-alive>
<component :is="composantActif"></component>
</keep-alive>
Cela permet de conserver le DOM et les données réactives même lorsque le composant n’est plus affiché.
Composants asynchrones
Un composant asynchrone charge son code uniquement lorsqu’il est nécessaire, ce qui améliore les performances du chargement initial.
Dans Vue 2, un composant asyncrhone est défini comme une fonction recevant resolve et reject :
Vue.component('composant-async', (resolve, reject) => {
setTimeout(() => {
resolve({
template: '<div>Chargé dynamiquement</div>'
});
}, 1000);
});
Dans Vue 3, on utilise defineAsyncComponent, qui attend une fonction retournant une Promise :
const { defineAsyncComponent } = Vue;
const composantDiffere = defineAsyncComponent(() =>
new Promise((resolve) => {
setTimeout(() => {
resolve({
template: '<div>Asynchrone en Vue 3</div>'
});
}, 1000);
})
);
Vue.createApp({
components: {
'composant-differe': composantDiffere
}
}).mount('#app');
Utilisation pratique avec les outils de build
Dans un projet construit avec Vite ou Vue CLI, les composants asynchrones sont généralement implémentés via import() pour activer le code-splitting.
- Vue 2 :
() => import('@/components/AsyncComp.vue') - Vue 3 :
defineAsyncComponent(() => import('@/components/AsyncComp.vue'))
Cette technique permet de charger chaque composant dans un fichier JavaScript séparé, téléchargé uniquement au moment de son affichage.