Comprendre template dans Vue.js
Dans une application Vue.js, la structure visuelle peut être définie de plusieurs manières. On peut écrire directement dans une page HTML, utiliser un composant avec une propriété template, ou passer par un fichier .vue. Ces options sont toutes valides, mais n’ont pas les mêmes implications selon le contexte.
Vue permet ainsi d’intégrer un template directement dans le script JavaScript, via createApp() ou dans la déclaration d’un composant. Cela peut être très pratique dans les projets légers, les démonstrations rapides ou les petits modules autonomes. Mais cette méthode atteint vite ses limites dès que l’interface devient plus complexe ou que la réutilisation devient nécessaire.
Nous allons explorer cette forme d’écriture, ses avantages dans les cas simples, ses inconvénients à mesure que l’application grandit, et en quoi elle constitue un pont vers les composants monofichiers (.vue).
À quoi sert un template dans Vue.js ?
Le template est la partie d’un composant qui décrit ce que l’on veut afficher à l’écran. Il s’agit d’un bloc de balisage HTML enrichi par la syntaxe Vue : accolades doubles ({{ }}), directives (v-if, v-for, v-bind, etc.), et gestion des événements (@click, @input, etc.). C’est dans le template que l’on construit la structure visuelle de l’interface, en y injectant dynamiquement les données du composant.
Vue se charge ensuite de relier ce balisage aux données, aux méthodes et aux événements déclarés ailleurs dans le composant. Le template est donc la partie visible du code, mais aussi le point de contact entre les données et l’utilisateur.
Il peut être écrit de plusieurs manières, selon l’architecture du projet : dans une page HTML externe, sous forme inline dans un composant, ou dans un fichier .vue structuré. C’est ce que nous allons explorer.
Déclaration inline : où et comment ?
Un template inline s’écrit directement dans la déclaration du composant, au sein d’un objet passé à Vue.createApp() ou à app.component(). Cela permet de créer des interfaces sans dépendre d’un fichier HTML externe ni d’un fichier .vue.
Exemple simple avec createApp() :
const app = Vue.createApp({
data() {
return {
message: 'Bonjour Vue !'
};
},
template: `
<div class="p-4 bg-blue-100 rounded">
<h1 class="text-xl font-bold">{{ message }}</h1>
</div>
`
});
app.mount('#app');Dans cet exemple, le template est directement intégré dans le script. C’est simple, lisible, et suffisant pour un composant autonome.
Même principe avec un composant global :
app.component('alert-box', {
props: ['text'],
template: `
<div class="border border-red-300 bg-red-100 p-3 rounded text-red-800">
⚠️ {{ text }}
</div>
`
});Ici, le composant alert-box est défini avec une propriété template, ce qui permet de l’enregistrer sans fichier séparé. Il peut ensuite être utilisé comme n’importe quel composant Vue.
Cas d’usage : quand préférer cette méthode ?
La déclaration inline d’un template est particulièrement utile dans certains contextes, notamment lorsqu’on cherche à aller vite, rester léger ou tester une idée sans mettre en place toute une architecture. C’est une méthode que l’on retrouve souvent dans :
- Les prototypes rapides, où l’on veut valider une interaction sans configurer un projet complet.
- Les démonstrations pédagogiques, comme celles de ce blog, qui doivent rester simples à lire et à reproduire sans outil externe.
- Les petits composants indépendants, comme une alerte, une info-bulle ou un bouton réactif, qui ne justifient pas un fichier
.vueséparé.
Dans tous ces cas, écrire le template dans le même fichier que le reste du code permet de rester concis, tout en conservant toute la puissance de Vue : gestion des événements, liaison dynamique, directives conditionnelles…
app.component('fav-button', {
data() {
return { liked: false };
},
template: `
<button @click="liked = !liked" class="px-3 py-1 rounded border"
:class="liked ? 'bg-blue-500 text-white' : 'bg-gray-200'">
{{ liked ? 'Ajouté' : 'Ajouter' }}
</button>
`
});Cet exemple avec un bouton « favori » montre un composant autonome, clair, et directement utilisable sans configuration spécifique. Il illustre bien ce que permet un template inline.
Autres formes de template “non inline”
Lorsque l’on ne souhaite pas écrire le template directement dans le script, il est aussi possible de le placer dans le HTML à l’aide d’un <template> identifié. Cette approche était courante avant l’apparition des Single File Components (.vue) et reste utile dans un environnement sans outil de compilation.
<template id="lightbox-template">
<div v-if="visible" class="lightbox">…</div>
</template>Dans le script, on fait référence à ce template avec template: '#lightbox-template' :
const app = Vue.createApp({
components: {
lightbox: {
props: ['image', 'visible'],
emits: ['close'],
template: '#lightbox-template'
}
}
});Ce n’est pas un template inline, car le contenu est défini en-dehors du script. Mais ce n’est pas non plus un composant .vue : on reste dans une architecture modulaire légère, sans compilation.
Cette solution intermédiaire peut convenir si l’on tient à garder le HTML à part, tout en profitant des composants Vue.
Comparaison avec un fichier HTML externe
Lorsqu’on débute avec Vue.js sans outil de compilation, il est courant de conserver son interface HTML dans un fichier séparé, par exemple un index.html avec une div id="app". Cette méthode permet une séparation claire entre le HTML et le JavaScript, mais elle peut vite rendre la lecture plus fragmentée.
Déclarer un template directement dans le script permet au contraire de centraliser le balisage, la logique et les données dans un même bloc. Cela rend le composant plus autonome et plus facile à lire, surtout s’il reste de taille modeste.
Vue.js propose aussi une autre approche avec les fichiers .vue — des fichiers uniques combinant template, script et style — que nous aborderons dans un autre article. Ils permettent une organisation plus avancée, mais nécessitent un environnement de compilation.
Pour l’heure, la déclaration inline reste une option simple, directe et puissante, particulièrement adaptée aux projets légers ou aux composants ponctuels.
Exemple concret : un composant Lightbox inline
Imaginons que nous souhaitons afficher une image agrandie dans une modale lorsqu’on clique sur une miniature. C’est exactement le rôle d’un composant lightbox : un élément réutilisable, discret, mais très utile dans une interface interactive.
Avec Vue.js, nous pouvons le déclarer directement dans le script grâce à la propriété template, sans passer par un fichier HTML séparé ni un fichier .vue.
export default {
name: 'lightbox',
props: ['image', 'visible'],
emits: ['close'],
template: `
<div v-if="visible" class="fixed inset-0 bg-black bg-opacity-60 flex items-center justify-center z-50">
<div class="bg-white p-4 rounded shadow-lg max-w-lg w-full relative">
<button @click="$emit('close')"
class="absolute top-2 right-2 text-gray-600 hover:text-black text-2xl">×</button>
<img :src="image" alt="Image agrandie" class="w-full h-auto rounded">
</div>
</div>
`
};Ce composant :
- Attend deux props :
image(URL de l’image à afficher) etvisible(booléen qui contrôle l’apparition de la modale). - Utilise
v-ifpour ne s’afficher que lorsqu’il est activé. - Émet un événement
closequand l’utilisateur clique sur le bouton×, que le parent pourra écouter avec@close="...".
Comment l’utiliser dans l’application ?
Dans un composant parent (ou directement dans createApp() si l’on n’utilise pas de fichiers .vue), on peut l’intégrer ainsi :
import Lightbox from './components/Lightbox.js';
const app = Vue.createApp({
data() {
return {
selectedImage: null
};
},
components: { lightbox: Lightbox }
});
app.mount('#app');Et dans le template du parent :
<lightbox :image="selectedImage" :visible="!!selectedImage" @close="selectedImage = null"></lightbox>Ce pattern simple permet de créer des composants réactifs, clairs et autonomes, sans avoir recours à une chaîne de compilation.
Conseils et limites
Les templates inline sont très pratiques, mais ils ne conviennent pas à tous les cas de figure. Voici quelques repères pour bien les utiliser.
Quand c’est une bonne idée
Un composant simple, autonome, localisé — comme une modale, un tag, un bouton, ou ici une lightbox — est un bon candidat pour une déclaration inline. Cela permet d’avoir tout le code dans un même fichier, sans dépendances externes ni build.
Quand cela devient risqué
Dès que la structure HTML devient longue, ou que l’on ajoute beaucoup de logique, le template inline devient difficile à lire. Les erreurs sont plus difficiles à repérer, la mise en page devient confuse, et le code perd en maintenabilité.
Conseil
Si un composant dépasse une dizaine de lignes dans le template, ou si vous commencez à dupliquer des blocs HTML, il est temps de penser à l’extraire dans un fichier .vue. Le gain en clarté et en réutilisabilité sera réel.
Enfin, souvenez-vous qu’un template inline doit toujours retourner un seul élément racine. Cela signifie que tous les éléments internes doivent être englobés dans une <div>, un <section>, ou un élément équivalent. Si ce n’est pas respecté, Vue affichera une erreur.
Conclusion du chapitre
Déclarer un template directement dans un composant est une manière simple et élégante de démarrer avec Vue.js, sans outils complexes ni fichiers supplémentaires. Cette approche permet de penser composant tout en restant dans une architecture légère.
Elle est idéale pour :
- Tester rapidement une idée,
- Créer un petit composant ciblé,
- Maintenir la logique regroupée dans un même fichier.
Mais elle a ses limites. Dès que la complexité augmente, il vaut mieux basculer vers des fichiers .vue, plus adaptés à une structuration propre du code.
Un template inline n’est ni une étape transitoire, ni une mauvaise pratique : c’est une option à part entière, parfaitement légitime, si elle est utilisée avec discernement.
