Appearance
1. Single File Components
Présentation
Dans un projet Javascript sans framework, il est nécessaire de séparer son code en fichiers HTML, CSS et Javascript. Cette séparation par type est efficace lorsque l’on souhaite s’intéresser à la structure ou la mise en page du projet spécifiquement. Toutefois, elle est beaucoup moins pertinente lorsque l’on s’intéresse à l’ensemble du code en œuvrant autour d’un élément visuel particulier de notre page.
Les Single File Components, ou composants mono-fichiers, nous apportent ici une solution efficace pour compartimenter notre code autrement. Ces fichiers à l’extension .vue, sont capables de contenir un fragment de notre structure HTML, le tout accompagné d’une portion de code CSS et Javascript de notre site.
Grâce à ce format, vous pouvez simplement rassembler l’ensemble du code concernant un élément visuel de votre site, que l’on nommera alors un composant (component en anglais).
Ces composants auront également l’avantage d’être facilement réutilisables plusieurs fois au sein de notre application, avec éventuellement des paramètres différents à chaque utilisation.
Cette approche par composant rejoint le principe de séparation des préoccupations défendu par Vue.js. Elle invite à une construction plus intelligente de nos projets, qui vous permettra également de plus facilement réutiliser des parties de vos précédents sites ou de sites créés par d’autres développeurs.
Structure de fichier
Les Single File Components se découpent en trois parties distinctes, correspondant aux trois types de code présents dans un projet frontend : HTML, Javascript, CSS.
Pour ce cours, nous nous appuierons sur un exemple : nous souhaitons créer un site web présentant l’ensemble des chiens présents dans un chenil. Pour cela, nous aimerions avoir des blocs formant une mosaïque, et qui contiendront chacun une photo, le prénom et la race d’un chien du chenil.
Voici la base du Single File Componant représentant ce bloc :
jsx
<template>
<div class="dog-card">
<img class="picture" src="https://my-best-kennel.com/pictures/45.png"/>
<div>
<h2 class="firstname">Pluto</h2>
<p class="breed">Saint-Hubert</p>
</div>
</div>
</template>
<script>
export default {
name: 'DogCard'
}
</script>
<style>
.dog-card {
display: flex;
}
h2 {
font-size: 20px;
}
</style>On distingue bien dans cet exemple une séparation en trois parties assurée par les balises <template>, <script> et <style>. Nous allons détailler le rôle de ces différentes parties.
La balise <template>
Cette première balise contient simplement la structure HTML correspondant à l’élément que nous souhaitons construire. On y retrouve des balises HTML standards, nous permettant d’ajouter ici une image, et un bloc contenant un titre et un paragraphe.
Nous verrons dans les prochains chapitres que cette partie inclut des mécaniques supplémentaires, nous permettant d’inclure le contenu de certaines variables, ou encore d’inclure des logiques itératives et conditionnelles grâce à des attributs additionnels : les directives.
WARNING
⚠️ Attention, il est important de veiller à ce que la balise <template> ne contienne toujours qu’un seul enfant direct, comme ici avec <div class="dog-card"> et non plusieurs balises. Sans cela, Vue.js ne sera pas capable de correctement traiter votre composant.
La balise <script>
Comme dans un projet standard, cette balise permet d’inclure du code Javascript dans notre projet. Vous pouvez donc, si vous le souhaitez, y importer des librairies Javascript, y définir des fonctions, ou toutes autres logiques de programmation permises par le langage.
On y retrouve toutefois un élément particulier : une commande qui construit un objet et qui l’exporte comme un élément par défaut. La commande peut d’ailleurs être décomposée comme ceci :
jsx
<script>
const componentConf = { name: 'DogCard' }
export default componentConf
</script>Cet export est essentiel au bon fonctionnement de notre composant. A chaque fois que nous ferons appel à notre composant quelque part dans notre projet, les informations de cet objet exporté seront récupérées pour configurer le comportement attendu de l’instance de notre composant. Nous appellerons donc cet objet la configuration de notre composant.
Rappelez-vous que les composants sont faits pour être utilisés potentiellement plusieurs fois dans une application. En ce sens, ils se rapprochent beaucoup des classes qui seront ensuite instanciées en différents objets, dans lesquels les données pourront différer d’une instance à l’autre. Vue.js s’appuie d’ailleurs en arrière-plan sur un système de classes pour faire fonctionner les composants. Cet objet, que l’on va exporté, correspondra en quelques sorte à la définition de notre classe.
Pour le moment, notre objet ne présente qu’une seule information : un nom. Nous verrons dans les prochains chapitres qu’il est possible d’y inclure bien d’autres éléments, comme des formes d’attributs et de méthodes pour nos composants.
INFO
📢 Dans les premiers chapitres de ce cours, nous définirons la configuration de nos composant en utilisant la syntaxe historique de Vue.js issue de sa version 2, aujourd’hui appelée l’API Options. Sachez qu’il existe également une syntaxe plus moderne, mais un peu moins intuitive nommé l’API Composition. Afin d’accéder à une documentation adaptée à la syntaxe de ce cours, veillez à définir la préférence de la documentation sur le site de Vue.js sur Options :

La balise <style>
Comme vous l’avez sans doute déjà deviné, cette balise vous permet de définir le code CSS que vous souhaitez généralement associer à votre composant.
A noter toutefois que le style que vous définirez s’appliquera par défaut à l’ensemble de votre projet. Si par exemple d’autres titres h2 sont présents ailleurs dans votre projet, ils seront ici également affecté par votre code. Pour réduire la porté de votre code CSS aux balises directement présentes dans votre balise <template>, il vous suffit d’ajouter l’attribut scoped à votre balise <style> :
jsx
<style scoped>
[...]
</style>Si vous souhaitez limiter le style à votre composant, mais tout de même affecter les autres composants définis à l’intérieur de celui-ci, vous devrez ajouter >>> avant chaque définition concernée :
jsx
<style scoped>
>>> h2 {
font-size: 20px;
}
</style>
