Vue.js pour les débutants ! (PARTIE 1)
Si vous ne l’avez pas lu, je vous invite à lire l’INTRODUCTION (Partie 0) de ce tutoriel, car il va y avoir pas mal de changements, retrouvez l’intro ici
❤️ 💛 NEW COURSE ||||| 2019 |||||| VUE.JS 3 |||||||
https://medium.com/@thibault60000/vue-js-for-beginner-pour-d%C3%A9butants-part-1-2019-en-fr-2a80b2a50e37
NEW COURSE ||||| 2019 |||||| VUE.JS 3 ||||||| 💙 💜
Le but ici n’est pas d’expliquer Vue.js, son historique ou ses points positifs et/ou négatifs mais simplement de vous expliquer comment démarrer facilement et ce qu’il est possible de faire.
Tutoriel fortement inspiré de celui du blog ippon, un cabinet de conseil bien sympa! :) Merci à eux pour leur explication
Nouveau tutoriel Juillet 2019 : React + GraphQL + StyledComponents + Apollo + Prisma Ici
Installation
Il faut commencer par télécharger Node.js actuellement en version 10.6.0 qui inclut NPM (libre à vous d’utiliser Yarn si vous préférez)
Pour installer la dernière version de NPM en global il faudra effectuer la commande npm install npm@latest -g
Pour installer le client Vue il faut installer vue-cli avec la commande npm install -g vue-cli
Je recommande d’installer le plugin Chrome pour Vue.js très facile d’utilisation, il ressemble fortement à celui de React si vous avez l’habitude
Bien entendu vous aurez besoin d’un IDE ! Pour ma part j’utilise VS Code !
Pour créer le projet il faut utiliser la commande vue init webpack mon_projet (en minuscule le nom) et là différents choix vous sont proposez, pour l’instant on laisse tout par défaut et je choisi d’utiliser NPM et d’activer EsLint.
On se place ensuite dans le répertoire du projet avec cd mon_projet
Et pour lancer le projet on va simplement effectuer un npm install suivi d’un npm run start et aller http://localhost:8080/
Les premiers fichiers
App.vue : fichier principal qui englobe tous les composants de l’application. On y retrouve trois sections : <template> , <script> et <style> qui permettent respectivement de mettre du code HTML (le template), le code JavaScript (les données, les méthodes, les événements…) et le code CSS
Le fichier index.html est quand à lui le point d’entrée de l’application. Il comporte uniquement le boilerplate html de base ainsi qu’une div avec l’id App qui nous servira de point de départ du code de l’application
Et le main.js qui est le fichier “racine” de l’application. C’est lui qui va faire le lien entre la vue et le modèle dans notre cas (car oui, Vue.js utilise le MVVM).
On voit ici qu’on importe Vue et qu’on importe notre composant App. On spécifie que le mode de production n’est pas active (on est en dev) et on créer un nouvel objet Vue qui prend en paramètre el qui est l’élément HTML qui a pour valeur notre point d’entrée de l’application (la balise Div avec l’id app), en deuxième argument la liste des composants enfants (ici App) et le template qui sera afficher dans la balise div#app
Notre premier composant
Déjà c’est quoi un composant ?
C’est un Template constitué de balise HTML, du JavaScript (comportement du composant) et du style (le design de notre bête !)Et Webpack c’est quoi ? C’est une dépendance qu’on a installé de manière totalement transparence grâce au client vue. Il nous permet de séparer la définition même d’un composant dans un fichier javascript dédié ce qui nous permet d’avoir notre style, template et js dans un même fichier
Commençons par créer un composant HelloWorld
Un composant qu’on dira “natif” peut être écrit de la manière suivante :
Attends avant de recopier ;)
export default {
template: '<div> {{ message }} </div>',
data() {
return {
message: 'Hello World'
}
}
}
Mais on va pas s’embêter avec cette nomenclature barbare ! Grâce à Webpack et le module vue-loader (qui lui aussi est pris en compte de manière transparente) on va pouvoir extraire le template, le style et le javascript dans des zones séparées comme ci-dessous :
<template>
<div>
<h1> Hello World
</div>
</template><script>
export default {}
</script><style>
</style>
Comme pour notre composant App.vue
Créons donc notre premier vrai composant, dans le dossier /composants créez un fichier HelloWorld.vue comme ci-dessous et nous allons essayer de comprendre sa structure
Si un fichier du même nom existe déjà supprimez le !
ATTENTION : On utilise ici Eslint donc la moindre guillemet au lieu d’une quote, le moindre espacement mal gérer provoquera une erreur à la compilation, désactivez le si vous ne voulez pas d’erreur !!
Le lien entre App (composant principal) et HelloWorld se fait grâce à l’import dans la balise <script> du App.vue ainsi qu’à son appel dans l’objet components comme si dessous
Vous devez à la suite de là voir :
Transmettre une valeur du composant Parent au composant Enfant
Dans notre App.vue on oublie cette histoire de HelloWorld.vue et on remplace son appel seulement par Hello.vue (que l’on va créer juste après). On passe directement des valeurs en attribut du sélecteur de “Hello” comme suit :
(firstname, lastname, from et img)
Et on va ainsi pouvoir récupérer ces valeurs dans le composant Hello grâce aux props (même niveau que data() )
On obtient ainsi le même résultat qu’auparavant avec une deuxième fois le logo (ou n’importe quelle image que vous aurez mis) grâce à la directive v-bind:src (aussi utilisé simplement avec :src)
Il est possible d’utiliser des autres data en même temps que les props comme ci-dessous, attention toutefois à ne pas créer de doublons entre data et props, par exemple :
Dans le cas présent, hello va fonctionner, mais on aura une erreur au niveau de la data “from”
[Vue warn]: The data property “from” is already declared as a prop. Use prop default value instead.
Modifier les données d’un composant par la Vue
Nous allons parler des fameux Two-Way Binding, autrement dit de “lien bi-directionnel” qui permet d’associer une champs de saisie du DOM à une donnée du composant.
On souhaite par exemple pouvoir changer notre nom et prénom ainsi qu’un petit message d’accueil. En reprenant notre fichier Hello.vue on supprime une petite partie du code pour qu’il ressemble à ceci :
On peut alors utiliser v-model pour lier le champs (input) avec une valeur dans les data. Dans le cas présent on utilise un objet person qu’on a créé qui possède plusieurs propriétés (firstname et lastname). Et une propriété message (tous des string). On peut alors simplement utiliser firstname par exemple comme un objet grâce à person.firstname.
On obtient alors :
Et on peut changer les données des champs, ce qui modifie la page en temps réel
Plusieurs occurrences d’un même composant
Il est possible d’appeler plusieurs fois un même composant, ajoutons dans App.vue deux instances du même composant Hello.
Et testons de modifier un des composant, on voit que seule une instance se modifie, l’autre n’est pas impactée par les changements.
Modifier des données à partir de fonctions JavaScript
On va pouvoir modifier les données d’un de plusieurs manières :
- La première grâce à des fonctions spécifiques à un composant donné (modification de l’état) grâce à methods
- La deuxième concerne toujours un composant donné mais cette fois si grâce à une modification d’état automatique (mise à jour de l’état) grâce à computed
- La troisième se fait grâce aux fonctions appelées automatiquement durant le cycle de vie d’un composant.
Commençons par la première manière (methods). Nous allons créer un nouveau composant nommé cars.vue qui va permettre :
- d’afficher une liste de voitures avec la directive v-for qui permet de parcourir une liste de voiture contenue dans les données du composant
- d’afficher un bouton permettant d’ajouter une nouvelle voiture à la liste
IMPORTANT : La directive v-for doit également être accompagné de v-bind:key pour donner une clé unique à chaque occurrence de car parmis les cars (dans le cas présent on utilise car.name mais il serait plus judicieux d’utiliser un identifiant unique
Créons donc ce composant ! (et expliquons ensuite sa structure)
Petit rappel : On englobe nos balises de la template dans une div car la balise template n’accepte qu’un seul enfant
Commençons les explications: On retrouve une liste qui affiche des propriétés d’un objet car (comme pour notre objet “person” dans l’exemple précédent.
On retrouve un button avec le raccourci @click qui est un raccourci de la directive v-on:click qui permet de détecter un événement click survenant dans le DOM et d’exécuter du code à son déclenchement (dans le cas présent, la fonction addCar )
Dans notre exemple la fonction addCar() change les Data du composant (et donc son état ) à chaque appel de la fonction via le clic sur le bouton.
Remarque : Il existe beaucoup d’autres événements comme @dbclick , @keyup.esc …etc
Admettons maintenant que l’on souhaite afficher le nombre de voitures dans notre liste, on va avoir besoin d’un compteur. Le mieux pour gérer ce cas c’est Computed.
Cela va nous permettre de mettre à jour automatiquement notre liste après avoir ajouter une voiture dans la liste.
Ajoutons donc un <p> qui se chargera d’afficher notre compteur et créons un computed : counter() pour gérer ça.
On remarque ici à la 9ème ligne {{ counter }} c’est cette valeur qui va nous permettre d’afficher le résultat de la méthode counter() dans computed.
Les fonctions dans computed sont invoquées automatiquement et sont exécutées uniquement lorsque les données qu’elles manipulent (ici l’objet cars) sont modifiées !
Donc à chaque fois qu’on ajoute une voiture dans notre tableau grâce à addCar() la computed counter() est exécutée.
Pour tester, supprimons dans App.vue les appels à Hello.vue et ajoutons un appel à Cars.vue
C’est bien beau de créer 40 000 fois le même élément dans notre liste mais on aimerai rendre sa dynamique et pourquoi pas avoir une valeur par défaut dans notre liste de voitures.
On part du principe que notre liste de voiture est initialement vide dans notre composant :
Dans notre exemple, j’ai ajouté des props (pour rappel: les props sont les informations que l’on récupère du parent lors de l’appel du composant)
J’ai également ajouté dans mounted une ligne permettant d’ajouter une voiture dans le tableau cars avec comme valeurs celles récupérées dans props
La méthode mounted est ce que l’on appelle une HOOK
Les Hooks sont des fenêtres du cycle de vie d’une instance de Vue pendant laquelle des actions peuvent être déclenchées. Vous pouvez retrouver chacune d’elle ici. On va notamment retrouver mounted, beforeMount, beforeUpdate, beforeCreate, created, updated, beforeDestroy et destroyed
Pour que notre exemple fonctionne il va falloir changer un peu notre App.vue pour que notre composant Cars récupère une valeur par défaut dans ses props
On se retrouve avec une voiture dans notre liste au chargement de la page (et donc lorsque le composant est mounted
Utilisation de vrais données : API REST
Bon c’est bien beau d’initialiser notre liste comme ça avec une props. Mais dans un cas concret on à besoin de données venant d’un serveur notamment grâce à l’utilisation d’un service REST.
Pour ce faire nous allons utiliser vue-resource qui est une dépendance (le client HTTP de Vue.js). Pour l’installer rien de plus simple :
npm install --save vue-resource
Ce qui ajoute la dépendance au package.json (et qui l’installe directement dans le dossier /node_modules
Pour les besoins de ce tutoriel nous allons également utiliser une “fausse”(mocks) API REST grâce à JSON Server pour tout gérer côté Front et ne pas s’embêter avec le côté Back !
npm install -g json-server
Il va donc nous falloir un jeu de données, dans le dossier /static de votre arborescence, créez un dossier /mocks dans lequel vous allez créer un fichier cars.json dans lequel vous allez créer de fausses données comme ci-dessous
Si tout est bon vous devriez pouvoir lancer la commande suivante pour lancer le serveur
json-server --watch static\mocks\cars.json
On a maintenant accès à 4 types d’URL :
- La liste des voitures http://localhost:3000/cars
- Les informations de chaque voiture http://localhost:3000/cars/{id}
- Les informations détaillées d’une voiture http://localhost:3000/cars/{id}/details
- Et la page d’accueil http://localhost:3000 (avec le résultat ci-dessous)
Maintenant que tout est en place !
Nous allons pouvoir importer vue-resource dans notre application dans notre Cars.vue
vue-resource va nous permettre d’accéder à des services $http et $resource, ce qui nous retournera dans les deux cas une promesse (promise) pour gérer les cas passants (API renvoie bien le flux JSON) et les cas d’erreurs.
Pour se faire on va simplement appeler le service $resource dans le mounted() du composant en remplissant le tableau cars avec ce que l’on récupère, et on affiche l’erreur si erreur il y a.
Pour se faire on va éditer l’objet http dans lequel on assignera root à notre URL comme ceci :
Lorsque l’on actualise la page on se retrouve maintenant avec nos données dans notre liste ;)
Voila ! On en a fini pour cette première partie ! Dans la seconde partie nous traiterons la transmission de valeur entre composants (enfant vers parent), le système de routing et Vuex et le Store global !
PARTIE 2 DISPONIBLE ICI