Comprendre les fondamentaux de Vue.js
Installation
1. Une version par environnement
Nous allons voir dans ce chapitre qu’il est possible d’installer Vue.js de différentes manières selon l’outillage d’un projet existant ou si vous démarrez un nouveau projet d’application SPA.
Il existe dans tous les cas deux versions de la librairie :
-
une version de développement : elle comporte un mode debug permettant d’afficher des avertissements dans la console et d’interagir avec plusieurs outils d’aide au développement (extensions dans le navigateur) ;
-
une version de production : c’est une version minifiée et allégée du mode debug et du code pour les outils d’aide au développement. Elle s’utilise lorsque votre site est en ligne pour que son chargement soit le plus rapide possible dans le navigateur.
Vue.js n’est pas compatible avec IE 8 et ses versions antérieures. Il ne peut être utilisé que par des navigateurs compatibles avec les versions ES 5 et ultérieures de JavaScript.
2. Via téléchargement manuel
Pour commencer à utiliser Vue.js, téléchargez la dernière version de la librairie sur le site officiel : https://vuejs.org/v2/guide/installation.html
Téléchargez la version de développement. Une fois le fichier vue.js téléchargé, placez-le dans le répertoire de votre site web et chargez-le dans votre page HTML via la balise .<script>
<script src="vue.js"></script>
3. Via l’inclusion d’un CDN (le plus simple)
Si vous ne souhaitez pas télécharger la librairie pour ne pas alourdir le poids de votre projet, vous pouvez également charger ce fichier depuis un serveur distant via le CDN (Content Delivery Network) suivant :
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
C’est la méthode d’installation la plus simple pour commencer à utiliser les fonctionnalités de Vue.js.
Comme la librairie est hébergée sur un serveur distant, vous ne pourrez pas travailler sur votre projet hors ligne.
Pour une mise en production, utilisez plutôt le CDN suivant pour la dernière version stable (v2.6.11) :
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>...
Outils de développements
1. VS Code et ses plugins
a. Installer et configurer VS Code
Visual Studio Code est un éditeur de code gratuit, édité par Microsoft, et l’un des plus utilisés aujourd’hui par les développeurs Vue.js. Il a la particularité d’être très léger et puissant à la fois. Il est également très extensible, grâce à ses milliers de plugins.
VS Code est disponible en téléchargement sur Windows, Mac et Linux à l’adresse suivante : https://code.visualstudio.com/Download
Une fois installé, ouvrez-le.
Cliquez sur le bouton Extensions à gauche de la fenêtre.
Tapez "Vue.js Workbox" :
Cliquez ensuite sur le bouton vert Install.
Vue.js Workbox est un package de plusieurs outils d’aide au développement.
-
vetur : permet la coloration syntaxique, l’autocomplétion, le formatage du code Vue.js et l’ajout de plusieurs raccourcis (snippets) permettant la génération de blocs de code préformatés.
-
vue-peek : permet de se rendre directement sur le fichier de définition d’un composant en cliquant sur sa balise personnalisée lors de son utilisation dans un template. Il est également possible d’afficher cette définition directement à l’écran sous la balise personnalisée du composant.
-
auto-rename-tag : permet de renommer une balise HTML ouvrante et sa balise fermante en même temps.
-
auto-close-tag : permet de créer automatiquement la balise fermante lors de la création d’une balise HTML.
-
npm : permet d’utiliser directement le gestionnaire de dépendance npm dans VS Code.
-
NPM IntelliSense : ajoute l’autocomplétion pour les modules npm lorsqu’on souhaite en importer dans notre code.
-
Prettier : permet le formatage du code JavaScript, TypeScript et CSS.
-
Sorting HTML and Jade attributes : permet de trier dans l’ordre les attributs d’une balise HTML.
-
Bracket Pair Colorizer : colore automatiquement les paires de parenthèses ou d’accolades avec une couleur différente pour mieux les repérer dans le code.
-
Import Cost VSCode : permet d’afficher sur la même ligne la taille...
Instance Vue.js
1. Hello World
Une application Vue.js consiste à créer une instance Vue à la racine du projet puis à enrichir celle-ci avec des composants et plugins.
Pour créer une instance Vue.js, il suffit de créer une instance de l’objet Vue en JavaScript avec le mot-clé new et de lui passer en paramètre un objet d’options :
let app = new Vue({ /* options */ });
Les options les plus couramment utilisées sont les suivantes.
-
el : prend en valeur un élément HTML de type Element ou une chaîne de caractères représentant un sélecteur CSS.
-
data : prend en valeur un objet qui représente le Modèle. Il liste l’ensemble des données réactives de l’instance. On dit aussi que la valeur de ces données à un instant t représente l’état de l’application.
-
template : prend pour valeur une chaîne de caractères HTML qui représente la Vue.
-
computed : prend en valeur un objet dont les méthodes, appelées propriétés calculées, calculent et retournent un résultat à partir des données du modèle lorsqu’elles sont modifiées. Le résultat est placé en cache (voir la section Traitement et formatage des données).
-
watch : prend en valeur un objet dont les méthodes, appelées observateurs, sont exécutées lorsqu’une donnée du modèle est modifiée (voir section Traitement et formatage des données).
-
methods : prend en valeur un objet avec des méthodes pouvant être appelées suite à une action de l’utilisateur ou à partir d’une autre méthode de cet objet.
-
Crochets du cycle de vie de l’instance : ce sont des méthodes (beforeCreated, created, mounted, destroyed, etc.) appelées automatiquement par Vue.js durant le cycle de vie de l’instance Vue. Nous les verrons plus en détail par la suite.
En matière de code, une instance Vue ressemblera donc à ceci :
Nous pouvons constater que les traitements métier peuvent se placer à différents endroits de l’instance, dans les propriétés calculées, les observateurs...
Virtual DOM et réactivité
1. Le système de liaison de données
Dans cette section, nous allons voir plus en détail le système de réactivité de Vue.js. Ce n’est absolument pas nécessaire pour commencer à utiliser Vue.js mais il peut être important de le comprendre pour éviter certaines erreurs. Si vous avez besoin de rafraîchir vos connaissances en JavaScript, n’hésitez pas à revenir au chapitre Notions essentielles de JavaScript.
Tout d’abord, penchons-nous sur le mécanisme que Vue.js utilise pour détecter les changements de données dans le modèle de notre instance Vue. Nous allons voir comment celui-ci est mis en place au cours du cycle de vie.
-
Entre les crochets beforeCreated et created.
Lors de l’instanciation de l’objet Vue, Vue.js instancie un observateur. Tout composant Vue.js a un observateur qui lui est lié. Vue.js boucle ensuite sur toutes les propriétés de l’objet data.
Il convertit chaque propriété en une nouvelle propriété dotée d’accesseurs/mutateurs (getters/setters). Cela permet, comme en programmation orientée objet, d’encapsuler une propriété et d’effectuer des traitements complémentaires lorsqu’on récupère ou que l’on modifie sa valeur.
Pour cela, Vue.js utilise la fonction statique defineProperty() du type natif Object du langage JavaScript.
Exemple d’utilisation de la fonction defineProperty() pour créer des getters et setters :
let data = {};
let message = "Hello World !";
Object.defineProperty(data, "message", {
get: function() {
console.log('appelle get');
return valeurB;
},
set: function(nouvelleValeur) {
valeurB = nouvelleValeur;
console.log('valeur modifiée');
},
enumerable : true,
configurable : true
});
console.log(data.message); // affiche "appelle get" puis "Hello World !"
data.message = "Salut !";...
Liaison de données
1. Liaison réactive uni-directionnelle
a. Afficher des données réactives avec l’interpolation texte
Dès qu’il s’agit d’afficher les données du modèle dans la vue, on parle d’interpolation. L’interpolation la plus basique dans Vue.js est d’utiliser les "moustaches", c’est-à-dire les paires d’accolades avec une expression JavaScript pour le contenu textuel dans votre DOM.
<span>{{ /* expression js */ }}</span>
Si, dans un template, on place une propriété du modèle contenue dans l’option data au sein d’une moustache, le tout est remplacé par la valeur de cette propriété.
let vm = new Vue({
el: "#app",
data: {
nom: "Martin",
},
template: `<span>Bienvenue {{ nom }}</span>`
});
Si, au cours du cycle de vie de l’instance, la valeur de la propriété nom change, alors cette modification est automatiquement mise à jour dans la vue.
b. Rendre un attribut réactif avec v-bind
Pour rendre réactif un attribut HTML, on utilise une autre forme d’interpolation, avec l’utilisation de la directive v-bind.
v-bind permet de lier n’importe quel...
Affichage des données dans la View
1. L’interpolation avec des données plus complexes
Nous avons vu précédemment comment utiliser l’interpolation avec les moustaches pour afficher un contenu textuel ou comment rendre un attribut réactif avec la directive v-bind.
Nous avons jusqu’à présent utilisé des données du modèle en valeur, mais il est possible d’utiliser des expressions JavaScript plus complexes.
-
Effectuer des opérations avec les données du modèle :
<p>{{ a + b * c / 2 }}</p>
-
Manipuler des données avec des méthodes renvoyant une chaîne de caractères ou un nombre :
<p>{{ message.split('').reverse().join('') }}</p>
Ici, on utilise la méthode split, qui renvoie sous forme de tableau la chaîne de caractères contenue dans message. On inverse les éléments de ce tableau avec la méthode reverse. Puis on concatène tous les éléments du tableau avec la méthode join, qui nous retourne la chaîne de caractères qui sera finalement affichée.
-
Utiliser des ternaires pour faire du rendu conditionnel :
<p>{{ isOK ? 'OK' : 'KO' }}</p>
Si la donnée du modèle isOK vaut true, alors on affiche OK, sinon KO.
-
Utiliser la liste de valeurs, objets et méthodes natives suivants :
Infinity, undefined, NaN, isFinite, isNaN, parseFloat, parseInt, decodeURI, decodeURIComponent, encodeURI, encodeURIComponent, Math, Number, Date, Array, Object, Boolean, String, RegExp, Map, Set, JSON, Intl, require.
En revanche, il n’est pas possible d’effectuer les actions suivantes.
-
Déclarer des variables.
-
Utiliser les mots-clés du langage JavaScript pour le contrôle de flux comme while, for, if, else, switch, etc. Seules les ternaires peuvent être utilisées.
-
Utiliser plusieurs expressions à la fois.
-
Utiliser des variables globales définies dans l’application.
2. La directive v-html
Il est parfois nécessaire...
Traitement et formatage des données
1. Valeurs traitées avec les propriétés calculées
Lorsque des données affichées sur votre page sont calculées en fonction de l’état des données de votre modèle, il est possible d’effectuer ce calcul directement dans la vue si celui-ci peut se faire par une simple expression.
Cela dit, si cette expression est assez longue, comme par exemple une manipulation de chaîne, il est préférable d’effectuer ce traitement dans le ViewModel via une propriété calculée. Imaginons que l’on souhaite afficher une chaîne de caractères qui n’excède pas une taille donnée et à laquelle on ajoute "…" à la fin :
<span>{{ message.length > taille ? message.splice(0, taille - 3)
.concat('', '...') : message }}</span>
On se rend vite compte que si l’on a plusieurs expressions comme celle-ci dans la vue, le code va devenir très chargé et va perdre en lisibilité.
Il est donc préférable, pour des calculs complexes nécessitant une longue expression ou plusieurs expressions, d’utiliser une propriété calculée.
Il s’agit d’une propriété liée à une ou plusieurs données de votre modèle qui pourra ensuite être liée à la vue de la même manière qu’une donnée classique du modèle de données.
Dès qu’une donnée du modèle est mise à jour, les propriétés calculées qui s’appuient sur celle-ci sont immédiatement recalculées et rafraîchies dans les templates qui les affichent.
Une propriété calculée se déclare dans un objet affecté à l’option computed d’une instance de composant ou d’une instance racine. Elle prend en valeur une fonction qui retourne la valeur calculée et s’utilise ensuite dans la vue de la même façon qu’une propriété du modèle.
computed: {
maProp1: function() { /* return resultat1 */ },
maProp2: function() { /* return...
Affichage de listes de données
1. Utiliser la directive v-for
La directive v-for permet de lister les éléments d’un tableau ou les propriétés d’un objet du modèle.
<ul>
<li v-for="item in liste">{{ item }}</li>
</ul>
Ici, liste représente le tableau ou l’objet du modèle. Lors du rendu, Vue.js itère sur chaque élément du tableau ou sur chaque propriété de l’objet et affiche un élément <li>. À chaque itération, la variable JavaScript item prend la valeur de l’élément ou de la propriété en cours et peut être employée en tant que variable JavaScript dans le contenu de la balise utilisant v-for. Il est donc possible d’afficher comme ceci des tableaux complets de données de plusieurs centaines ou milliers de lignes en une ligne de code dans votre template.
Exemple avec un tableau :
let vm = new Vue({
el: "#app",
data: {
liste: ['pomme', 'orange', 'fraise', 'banane'],
},
template: `
<ul>
<li v-for="item in liste">{{ item }}</li>
</ul>
`
});
Résultat :
Il est possible de récupérer l’index en utilisant une variable en second argument de la directive.
<ul>
<li v-for="(item, index) in liste">{{ item }}</li>
</ul>
Exemple avec un tableau d’objets :
let vm = new Vue({
el: "#app",
data: {
personnes: [
{ prenom: 'Chuck', nom: 'Norris', age: 24 },
{ prenom: 'Bruce', nom: 'Lee', age: 27 },
{ prenom: 'Uma', nom: 'Thurman', age: 22 },
],
},
template: ` ...
Capture des évènements déclenchés par l’utilisateur
1. Directive v-on
a. Mettre à jour une donnée suite à un évènement du DOM
Pour capturer et réagir aux interactions de l’utilisateur via la souris ou le clavier, on utilise la directive v-on.
Cette directive peut être utilisée avec tous les évènements natifs du DOM. Pour en avoir une liste exhaustive, rendez-vous sur le lien suivant :
https://developer.mozilla.org/fr/docs/Web/Events
Cette directive est l’équivalent de la méthode JavaScript elmt.addEventListener() qui permet d’associer un gestionnaire d’évènement à un élément du DOM pour un évènement donné.
Elle prend en argument l’évènement que l’on souhaite écouter et en valeur le nom de la méthode du ViewModel à exécuter, c’est-à-dire le gestionnaire d’évènement associé, lorsque cet évènement se déclenche.
<button v-on:click="monAction">cliquez ici</button>
Exemple :
let vm = new Vue({
el: "#app",
data: {
message: '',
}
methods: {
afficher() {
this.message = "clic détecté";
}
}
template: `
<button v-on:click="afficher">Cliquez ici<button>
<span>{{ message }}</span>
`
});
Résultat :
Il est également possible de passer autant de paramètres d’entrée qu’on le souhaite à la méthode :...
Gestion des styles CSS
1. Scoped styles
Si vous développez une SPA avec Vue-CLI et des composants monofichiers (fichiers avec l’extension .vue), il est possible de déclarer du code CSS (saas ou less également) entre les balises <style></style>, placées par convention à la fin du fichier.
Cela peut être pratique pour identifier rapidement le code CSS lié au composant. Toutefois, après la compilation par l’empaqueteur de code (Webpack pour Vue-Cli), le CSS de l’ensemble des composants est rassemblé dans le même fichier et s’applique à l’ensemble de l’application.
Cela peut donc occasionner des effets de bord si le CSS déclaré dans votre composant surcharge celui d’un autre composant.
Pour limiter la portée du CSS au composant uniquement, on utilise le mot-clé scoped dans la balise de style.
// au sein d'un fichier avec l'extension .vue
<style scoped>
/* code CSS */
</style>
De cette façon, vous pouvez placer ici le code CSS spécifique au composant.
2. Les styles dynamiques
Un des avantages de la liaison de données est de pouvoir manipuler dynamiquement la liste des classes de l’attribut class ou les propriétés CSS de l’attribut style, sur les éléments du DOM, en fonction des données du modèle.
Prenons par exemple l’affichage d’un carré dont le style dépend d’une propriété du modèle :
let vm = new Vue({
el: "#app",
data: {
taille: 100,
couleur: red
}
template: `
<div v-bind:style="'height:'+taille+'px;width:'+taille+'px;
background-color:'+couleur+';'"></div>
`
});...