Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Chaque page web HTML est codée intégralement, et peu réutilisable pour d'autres pages (hors include en php).
Une page web est relativement figée (sans javascript), et ne permet pas une interaction "temps réel" (un champ complété alimente une zone directement).
Le manque de découpage de la page ne permet pas de réutiliser tout ou partie de la page sur une autre page
Vue.js (aussi appelé plus simplement Vue), est un framework JavaScript open-source utilisé pour construire des interfaces utilisateur et des applications web monopages. Vue a été créé par Evan You et est maintenu par lui et le reste des membres actifs de l'équipe principale travaillant sur le projet et son écosystème.
Vue.js apporte la notion de composant (qui n'est pas nouvelle en soit, HTML intégre déjà la notion de composant), et permet un "binding" complet entre les éléments (mise à jour réciproque des éléments).
Vue.js apporte une structuration forte du développement front, une réutilisabilité importante avec la notion de composant et améliore l'interactivité de l'application et l'expérience des utilisateurs.
Vue.js nécessite un environnement NodeJs pour fonctionner. Le code écrit n'est pas directement exploitable par les navigateurs et implique un mécanisme de "traduction".
Un automatisateur de tâche est indispensable, tel que webpack ou, ViteJs qui est recommandé avec la version 3 de Vue.js.
Vue.js implique également une bonne connaissance de la syntaxe JavaScript et en particulier les versions ECMAScript 6 (ES6) et suivantes.
Les "concurrents" directs de Vue.js sont :
AngularJs (dont le développeur de Vue.js est issu), précurseur sur l'approche par composant, fondé par Google.
ReactJs, développé par Facebook
Lire par exemple :
Ce cours se base sur la version 3 de Vue.js. Attention vous trouverez beaucoup d'exemple en Vue.js 2 sur les forums et sites d'aide.
La documentation officielle se trouve ici sur le lien suivant
Assurez vous de disposer de nodeJs et de npm fonctionnels, testez avec la commande ci-dessous
npm --version
Pour créer un nouveau projet, tapez la commande suivante :
Lors de la première execution, la commande va vous proposer d'installer create-vue. Confirmez la proposition
Répondez aux différentes questions. Par défaut mettez toutes les questions sur non, sauf "Add Vue Router for single Page Application development" que vous pouvez mettre sur yes.
Executez les commandes suivantes :
La première commande accède au répertoire, la deuxième installe toute les dépendances (comme composer install
avec PHP/Syfmony), la dernière lance le serveur qui va s'occuper de compiler les fichiers et rendre l'application "Vue.js" utilisable dans tous les navigateurs.
Vous devriez voir un message vous proposant l'url de votre projet "compilé". Ouvrez-là et vous devriez avoir une page similaire à celle ci-dessous :
Dans le composant App.vue qui est créé par défaut, et qui est le point d'entrée de votre application, nous allons faire les premiers tests.
Nous allons définir une liste de 3 éléments, par exemple :
Si on souhaite rendre cette liste "dynamique", on peut définir des variables pour les notes. La syntaxe est identique à Twig pour les variables...
Si vous testez de nouveau ce code, vous aurez une erreur car les variables n'existent pas. Nous devons les définir.
Pour cela, dans la partie javascript de notre fichier App.vue, nous allons définir une "entrée" data, qui va contenir nos valeurs.
La déclaration pourrait être (en vue2 ou vue3 "classique":
Notre code dans la partie script se résume donc à :
node_module : contient toutes les dépendances de notre projet. Il est créé par la commande npm install
. Il ne faut rien modifier dans ce dossier, et ne jamais le gérer avec git. Son équivalent dans Symfony est vendor.
public : c'est le repertoire "public", qui contient les éléments type images, favicon, les fichiers uploadés par vos utilisateurs, ... Il a le même rôle que "public" dans symfony.
src : c'est note répertoire de travail, la très grande majorité de notre code se trouvera dans ce dossier.
index.html : c'est le fichier html de base qui est affiché dans le navigateur et qui va intégrer nos composants Vue.js. Sa syntaxe est décrite par la suite.
package.json (et son package-lock.json), sont la liste des dépendants installées, c'est l'équivalent du composer.json pour le back.
ligne 10 : ce élément, avec un id "app" est l'élément qui va pouvoir recevoir notre code, nous le verrons avec le fichier main.js. Vous pourriez avoir plusieurs balises recevant plusieurs parties Vue.js. Vous pourriez aussi avoir un habillage HTML défini dans cette page et un "morceau" géré par Vue.js.
ligne 11 : C'est l'intégration du fichier main.js qui va contenir tout notre code JavaScript et les composants Vue.js.
assets : votre CSS/SCSS ... global à votre projet. Les logos et images du site.
components : nos composants Vue.js, des parties d'une page, qui seront assemblés pour faire votre page globale.
router : contiendra nos routes de notre site, le lien entre l'URL, les pages Vue.js.
views : les pages "Vue.js", qui assemblent les composants.
App.vue : notre composant principal, décrit par la suite
main.js : le fichier utilisé par ViteJs pour faire le lien entre les fichiers Vue.js, et la page index.html.
Cette structure est la base, vous pouvez l'organiser autrement, et ajouter toute la décomposition nécessaire.
Ce fichier est construit selon la structure "classique" de Vue.js, décrite dans la partie suivante.
template : qui contient le code HTML de votre composant (une partie de votre page). Ce code peut exploiter lui même d'autres composants Vue.js. La balise template doit contenir un seul enfant dans le dom.
script : qui va contenir votre code JavaScript : les variables, les méthodes, les différents imports...
style : optionnel, pour contenir le CSS propre au composant.
Si les SFC nécessitent une étape de compilation, les avantages sont nombreux en contrepartie :
Créer des composants modulaires en utilisant une syntaxe HTML, CSS et JavaScript familière.
Templates précompilés sans coût de compilation au runtime
Meilleures optimisations à la compilation grâce à l'analyse croisée du template et des scripts.
Prise en charge nativement du remplacement de modules à chaud (HMR).
SFC est une caractéristique déterminante de Vue en tant que framework, et c'est l'approche recommandée pour utiliser Vue dans les scénarios suivants :
Applications à page unique (SPA)
Génération de sites statiques (SSG)
Tout front-end non trivial pour lequel une étape de construction peut être justifiée pour une meilleure expérience de développement (DX).
C'est le fichier clé de votre application, l'équivalent du index.php de Symfony, car c'est lui qui contrôle tout ce qui va se passer, c'est le point d'entrée. c'est dans ce fichier que l'on peut instancier des dépendances globalements (comme router ici)
Ligne 1 : Import de Vue.js, et du composant createApp pour construire l'application (utilisé ligne 7)
Ligne 2 : On importe notre composant Vue.js App.Vue pour pouvoir l'exploiter dans notre fichier, et ici l'injecter dans la page ligne 7
Ligne 3 : le router pour gérer nos routes. On l'associe à notre application (ligne 9)
Ligne 5 : on importe notre CSS (ou autre), pour l'appliquer globalement au projet. Si c'est du Scss/Sass, ViteJs se chargera de le compiler en CSS.
Ligne 7 : on instancie notre application Vue.js avec le composant App (importé ligne 2)
Ligne 9 : on associe à notre application "app", le router, ce qui nous permettra de l'utiliser partout.
Ligne 11 : Cette ligne vient "injecter" notre application vue, dans la page html (index.html), et très exaxctement dans la balise avec l'id "app"
Vue utilise une syntaxe de template basée sur HTML pour permettre de lier de manière déclarative le DOM rendu aux données de l'instance du composant sous-jacent. Tous les templates Vue sont du HTML syntaxiquement valide qui peut être analysé par des navigateurs et des analyseurs HTML conformes aux spécifications. A titre de comparaison ReactJs utilise du JSX pour décrire la partie HTML.
La forme la plus élémentaire de liaison de données est l'interpolation de texte à l'aide de la syntaxe "Moustache" (doubles accolades) :
Dans cet exemple msg
est une variable dont le contenu doit être défini dans votre code Vue.js.
Si vous souhaitez passer une variable dans une balise HTML (ou un composant Vue.js), ou dans un attribut, vous ne pouvez pas utiliser la syntaxe "moustache" avec les accolades. Vous devez passer par l'instruction v-bind
, exemple :
Dans cet exemple idDynamique
est donc la variable qui alimentera l'attribut id de la balise div.
Il existe une syntaxe "courte" qui peut s'écrire sans le v-bind
comme ci-dessous :
Si vous avez un objet JavaScript représentant plusieurs attributs qui ressemble à ceci :
Vous pouvez les lier à un seul élément en utilisant v-bind
sans argument :
Cette syntaxe va faire apparaître les deux attributs id et class dans votre objet. Le v-bind
est ici obligatoire, il n'y a pas de syntaxe courte.
Les variables entre accolades peuvent être manipulées comme toutes les variables, comme dans les exemples ci-dessous.
Si vous souhaitez construire un mot contenant du texte et une variable, vous pouvez utiliser la syntaxe ci-dessous :
${id}
est la variable id
dans la notation particulière dans le contexte d'une concaténation avec du texte et avec l'usage des ``
Coté JavaScript, la déclaration des variables se fait de manière conventionnelle avec des constants, ou des variables (let), des variables simples (textes, nombres, float, ...) ou des tableaux, des objets json.
Installation de Vue.js
Modifiez le composant App.vue pour ajouter des variables : un titre et un paragraphe de texte
Créer un deuxième composant. Comment l'ajouteriez vous dans le composant App.vue ?
Ajoutez 3 variables (note1, note2 et note3) et affichez ces 3 notes et la moyenne.
Ajoutez une variable de type tableau contenant une liste de mot. Affichez cette liste.
Le calcul de la moyenne de l'exercice précédent est pratique, mais si on souhaite l'utiliser à plusieurs endroits il faudra refaire le calcul. Par ailleurs, on pourrait exploiter une boucle en JavaScript, ou manipuler des variables qui se composent elles mêmes de plusieurs autres variables. Tout cela est possible avec Vue.js, en utilisant des propriétés calculées, dites computed
.
La syntaxe d'une propriété calculée est la suivante (dans la partie script) :
Une propriété calculée est une constante, avec un nom, l'instruction computed
, puis une fonction anonyme en JavaScript.
Pour fonctionner ce code nécessite d'importer l'instruction computed qui est native dans Vue.js avec la ligne ci-dessous :
Le code complet serait donc :
L'utilisation dans la partie template se fait en considérant moyenne comme une variable classique. On peut donc l'utiliser pour un affichage avec {{ moyenne }}
ou dans des tests ou boucles, ou d'autres opérations.
Nous utiliserons la notation qui est préconisée avec la version 3 de Vue.js le "mode Composition API" ()
vite.config.js : c'est l'automatisateur de tâches (comme gulp ou webpack, Vue.js 3 recommande l'usage de qui est plus rapide et performant). Nous reviendrons sur ce fichier en BUT3. Il récupère tous les éléments du dossier src/, va les traduires en du JavaScript compréhensible par les navigateurs et en faire un seul et unique point d'entrée.
Si on utilise vue en mode "composant" () (c'est à dire avec des fichiers .vue ou SFC (single file component)) et en mode Composition API, un fichier .vue à les éléments suivants :
avec autocomplétion et vérification des types pour les expressions dans le template.
Cela ne concerne que l'approche par "composition" de Vue.js 3. La source de cette partie est la traduction de la documentation ici :
Comme tous les langages, il est possible d'avoir des conditions/tests, des boucles en Vue.js. Bien que Vue.js soit un framework JavaScript, les boucles et tests peuvent être soit dans le script (et donc avec une syntaxe JavaScript classique), soit dans la partie template, et dans ce cas on utilise la syntaxe de Vue.js décrite ci-après.
Cette partie reprend la traduction de la documentation officielle se trouvant ici : https://vuejs.org/guide/essentials/conditional.html
v-if
La directive v-if
est utilisée pour restituer conditionnellement un bloc. Le bloc ne sera rendu que si l'expression de la directive retourne une valeur évaluée à vrai.
Dans cet exemple awesome
doit être une variable définie dans la partie script.
v-else
Vous pouvez utiliser la directive v-else
pour indiquer un bloc "sinon" lié à un v-if
:
Un élément v-else
doit immédiatement suivre un élément v-if
ou un élément v-else-if
sinon il ne sera pas reconnu.
Dans cet extrait de code la ligne 1 contient la notation @click
(qu'on peut aussi écrire v-on:click
) qui va déclencher quelque chose lors d'un clic. C'est le déclenchement d'un événement sur le DOM. Nous y reviendrons par la suite. A chaque clique, la variable awesome
recevra son inverse.
Testez le code ci-dessus avec le bouton.
v-else-if
Le v-else-if
, comme son nom l'indique, sert de bloc "else if" lié à un v-if
. Il peut également être enchaîné plusieurs fois:
Similaire à v-else
, un bloc v-else-if
doit immédiatement suivre un bloc v-if
ou v-else-if
.
Définir 5 notes, et pour chacune indiquer en Vue.js si elles sont supérieures à 10 ou non.
Modifier le code pour différencier les notes entre 8 et 10
v-if
avec <template>
Puisque v-if
est une directive, elle doit être attachée à un seul élément. Mais que se passe-t-il si nous voulons basculer plus d'un élément ? Dans ce cas, nous pouvons utiliser v-if
sur un élément <template>
, qui sert de conteneur invisible. Le résultat du rendu final n'inclura pas l'élément <template>
.
v-else
et v-else-if
peuvent également être utilisés dans <template>
.
v-show
Une autre option pour afficher conditionnellement un élément est la directive v-show
. L'utilisation est sensiblement la même:
La différence est qu'un élément avec v-show
sera toujours rendu et restera dans le DOM; v-show
bascule uniquement la propriété CSS display
de l'élément.
v-show
ne prend pas en charge l'élément <template>
, et ne fonctionne pas avec v-else
.
v-if
vs. v-show
v-if
est un rendu conditionnel "réel" car il garantit que les écouteurs d'événements et les composants enfants à l'intérieur du bloc conditionnel sont correctement détruits et recréés lors des basculements.
v-if
est également paresseux : si la condition est fausse lors du rendu initial, il ne fera rien - le bloc conditionnel ne sera rendu que lorsque la condition deviendra vraie pour la première fois.
En comparaison, v-show
est beaucoup plus simple - l'élément est toujours rendu quelle que soit la condition initiale, avec un basculement basé sur CSS.
De manière générale, v-if
a des coûts de basculement plus élevés tandis que v-show
a des coûts de rendu initiaux plus élevés. Préférez donc v-show
si vous avez besoin de basculer quelque chose très souvent, et préférez v-if
si la condition est peu susceptible de changer à l'exécution.
Extrait de la traduction de la page : https://vuejs.org/guide/essentials/list.html
v-for
Nous pouvons utiliser la directive v-for
pour rendre une liste d'items basée sur un tableau. La directive v-for
nécessite une syntaxe spéciale de la forme item in items
, où items
est le tableau de données source et item
est un alias pour l'élément du tableau sur lequel on itère :
À l'intérieur de la portée du v-for
, les expressions du template ont accès à toutes les propriétés de la portée du parent. De plus, v-for
supporte également un second et optionnel alias pour l'index de l'item actuel :
Donnera le résultat ci-dessous.
Parent - 0 - Foo
Parent - 1 - Bar
Noté que contrairement au PHP par exemple, l'index est le second argument (c'est l'équivalent du "i") dans les boucles for, ou du "key" dans les foreach, mais par contre le sens et la syntaxe est identique à un forEach en JavaScript
Pour les v-for
imbriqués, les portées fonctionnent de la même manière qu'avec les fonctions imbriquées. Chaque portée de v-for
a accès aux portées de ses parents :
v-for
avec un objetVous pouvez également utiliser v-for
pour itérer sur les propriétés d'un objet. L'ordre d'itération sera basé sur le résultat de l'appel à Object.keys()
sur l'objet :
Vous pouvez également fournir un second alias pour le nom de la propriété (aussi appelé clé) :
Et un autre pour l'index :
v-for
avec une portéev-for
peut également prendre un nombre entier. Dans ce cas il va répéter le template un certain nombre de fois, basé sur une portée 1...n
.
Notez qu'ici n
démarre avec une valeur initiale de 1
au lieu de 0
.
v-for
sur le <template>
Comme le modèle v-if
, vous pouvez aussi utiliser une balise <template>
avec v-for
pour effectuer le rendu d'un bloc composé de plusieurs éléments. Par exemple :
Définir un tableau en JavaScript et l'afficher avec une boucle dans le template.
Générez un tableau de 10 variables en JavaScript, et l'afficher dans le template
Pour chaque note indiquer si elle est supérieure à 10 (en ajoutant une class green pour la couleur de la texte) ou red pour une note inférieure à 10.
Cette partie est une traduction/adaptation de la documentation officielle située : https://vuejs.org/guide/essentials/event-handling.html
Nous pouvons utiliser la directive v-on
, qui peut se résumer par le symbole @
, pour écouter les événements DOM et exécuter du JavaScript lorsqu'ils sont déclenchés. L'utilisation serait alors v-on:click="handler"
ou avec le raccourci, @click="handler"
.
handler
peut soit être du code JavaScript (on parle de gestionnaire en ligne ou inline handlers), soit une méthode définie dans la partie script (on parle de méthode gestionnaire ou method handler).
Avec la partie script :
ref() permet de rendre la propriété count
réactive. Il faut ajouter l'import suivant :
Cette solution est pratique pour les interactions simples, mais elle ne permet pas de réutiliser le code. Pour cela, il faut utiliser une méthode gestionnaire.
Notre bouton appelle ici une méthode nommée greet
. Cette méthode est définie dans la partie script. Elle affiche une alerte avec le message "Hello Vue.js!". Elle prend, automatiquement, en paramètre un événement natif du DOM.
On peut grace à cet événement accéder à la cible de l'événement, ici le bouton, et afficher son nom de balise HTML, ou récupérer des valeurs des attributs, etc.
Il est possible de passer nos propres paramètres à une methode associée à un événément. Par exemple, si on veut passer le nom de la personne à saluer, on peut faire :
Si on souhaite à la fois passer nos paramètres et récupérer l'événement natif du DOM, on peut faire :
La notation $event
est une syntaxe spéciale qui permet de passer l'événement natif du DOM en tant qu'argument à la méthode gestionnaire.
Il existe de nombreux événements (change, keyup, keydown, blur...) qui peuvent être écoutés et déclencher des actions.
Il est possible d'utiliser les événements de touche pour écouter les événements clavier. Par exemple, si on veut écouter l'événement keyup
sur un champ de saisie, on peut faire :
Ici, on écoute l'événement keyup
sur le champ de saisie et on exécute la méthode onEnter
lorsque la touche Enter
est pressée.
Créer un composant Counter
qui affiche deux boutons et un compteur. Le premier bouton permet d'incrémenter le compteur. Le compteur doit être réinitialisé à 0 lorsque l'on clique sur le second bouton.
Faire une boucle permettant d'afficher 4 compteurs. Testez le comportement des boutons.
Cette partie est une traduction/adaptation de la documentation officielle située : https://fr.vuejs.org/guide/essentials/forms.html
v-model
La directive v-model
est l'équivalent de v-bind
et v-on
en même temps. Elle permet de lier un élément du DOM à une propriété du composant.
v-model
peut être utilisé sur des entrées de différents types, des éléments <textarea>
, et <select>
. Il s'étend automatiquement aux différentes paires de propriétés et d'événements du DOM en fonction de l'élément sur lequel il est utilisé :
Les éléments <input>
de type texte et <textarea>
utilisent la propriété value et l'événement input ; <input type="checkbox">
et <input type="radio">
utilisent la propriété checked et l'événement change ; <select>
utilise value comme propriété et change comme événement.
Un ensemble d'exemple est disponible directement sur la documentation :
Champs Textes : https://vuejs.org/guide/essentials/forms.html#text
Champs TextArea avec plusieurs lignes : https://vuejs.org/guide/essentials/forms.html#multiline-text
Champs Checkbox unique ou en récupérant un tableau : https://vuejs.org/guide/essentials/forms.html#checkbox
Champs radio : https://vuejs.org/guide/essentials/forms.html#radio
Champs select (simple ou multiple) : https://vuejs.org/guide/essentials/forms.html#select
Par défaut, v-model
synchronise l'entrée avec les données après chaque événement input. Vous pouvez ajouter le modificateur lazy
pour enclencher la synchronisation après les événements change :
Si vous voulez que l'entrée de l'utilisateur soit automatiquement typée comme un nombre, vous pouvez ajouter le modificateur number à vos entrées gérées par v-model
:
Si la valeur ne peut pas être analysée avec parseFloat(), alors la valeur originale est utilisée à la place.
Le modificateur number est appliqué automatiquement si l'entrée possède type="number".
Si vous voulez que les espaces blancs des entrées utilisateur soient automatiquement supprimés, vous pouvez ajouter le modificateur trim à vos entrées gérées par v-model
:
Créer un formulaire avec les champs suivants :
Nom
Prénom
Affichez les valeurs saisies dans une balise <p>
.
Créer un formulaire avec les champs suivants :
Nom
Prénom
Affichez les valeurs saisies lorsque l'on appuie sur un bouton
Créer un formulaire avec les champs suivants :
Nom
Prénom
Genre (radio)
Afficher une phrase différente selon le genre sélectionné.
Cette séance est la traduction/adaptation de la documentation officielle se trouvant ici : https://vuejs.org/guide/essentials/lifecycle.html
Chaque instance d'un composant Vue passe par une série d'étapes d'initialisation lorsqu'elle est créée - par exemple, il faut paramétrer l'observation des données, compiler le template, monter l'instance sur le DOM, et le mettre à jour lorsque les données changent. En cours de route, des fonctions appelées hooks du cycle de vie sont également exécutées, donnant la possibilité à l'utilisateur d'ajouter son propre code à des étapes spécifiques.
Ci-dessous figure le diagramme du cycle de vie d'une instance.
Chaque case rouge est un moment où il est possible d'intéragir avec le composant.
Par exemple, le hook onMounted
peut être utilisé pour exécuter du code après que le composant ait terminé son rendu initial et créer les nœuds du DOM (sur la case route mounted
du schéma ci-dessus):
Il y a également d'autres hooks qui peuvent être appelés à différentes étapes du cycle de vie de l'instance, dont les plus couramment utilisés sont onMounted, onUpdated, et onUnmounted.
Il peut être intéressant d'utiliser ce hook pour effectuer des actions lorsque le composant est monté, mis à jour ou démonté. Par exemple, onMounted peut être utilisé pour récupérer des données depuis une API, et onUnmounted pour annuler les abonnements aux événements.
Les appels API peuvent se faire à chaque fois que nécessaire, dans des méthodes, dans des hooks, ...
Il est possible d'utiliser la méthode fetch pour récupérer des données depuis une API, qui est native à JavaScript. (voir https://developer.mozilla.org/fr/docs/Web/API/Fetch_API). Il existe également la librairie axios qui permet de faire des appels API plus facilement, et qui est très utilisée dans le monde Vue.js (et les framework frot en général). (voir https://axios-http.com/fr/docs/intro)
Axios n'étant pas natif, il faut d'abord l'installer avec la commande npm install axios
ou yarn add axios
.
Pour la suite, nous allons utiliser axios. Mais libre à vous d'utiliser la méthode que vous préférez. Le code et la logique seront sensiblement identiques
Créons un composant qui va récupérer des données depuis une API et les afficher dans la page.
Nous allons maintenant utiliser ce composant dans notre application.
Dans le composant API, nous avons déclaré une variable data
qui est initialisée à une chaîne de caractères vide. Nous avons ensuite utilisé le hook onMounted
pour récupérer les données depuis l'API et les stocker dans la variable data
.
Dans le composant App, nous avons importé le composant API et nous l'avons ajouté dans la liste des composants utilisés.
A partir de là, data
est accessible dans le template du composant App, et donc dans le template du composant API. Cette variable contient toutes les données retournées par l'API, et il est donc possible de l'afficher dans le template de manière plus fine.
Ce code ne fonctionne que si votre réponse json contient une entrée title
. Ce qui est le cas dans l'exemple ici qui renvoi la réponse suivante :
Si on souhaite récupérer les données précises sur une API, on peut paramètrer l'appel avec des variables.
Par exemple
Cette solution fonctionnelle, n'est pas très interactive, on pourrait donc récupérer cet id depuis un formulaire (ou l'URL par la suite).
Exemple :
En utilisant l"API : https://restcountries.com/#api-endpoints-v3-all
Récupérez et affichez la liste des pays (nom, capitale, langue)
Proposez une barre de recherche affichant les informations d'un pays de votre choix
Créer un composant qui récupère les données d'une API et qui les affiche dans la page sous la forme d'une liste ul/li. Mettre en vert les éléments si le champ completed
est à true
. Mettre en rouge les éléments si le champ completed
est à false
. (l'URL de l'API est https://jsonplaceholder.typicode.com/todos/4 renvoie un exemple de réponse à true).
Récupéré un tableau de tâches avec l'URL https://jsonplaceholder.typicode.com/todos et afficher les tâches dans une liste ul/li. Mettre en vert les éléments si le champ completed
est à true
. Mettre en rouge les éléments si le champ completed
est à false
.
Dans une application web classique, on utilise des URL pour changer le comportement de notre application, et le contenu des pages. Ce mécanisme fonctionne en envoyant une requête au serveur, qui nous retourne une page HTML.
Ce mécanisme est intéressant, mais ne permet pas d'avoir des applications dites "SPA" Single Page Application, c'est à dire des applications dont on à l'impression que l'intégralité de la page n'est jamais rechargeée, mais seulement une partie.
Dans une application monopage (SPA), le JavaScript côté client doit intercepter la navigation, récupérer dynamiquement de nouvelles données, et mettre à jour la page actuelle sans la recharger entièrement. Il en résulte généralement une expérience utilisateur plus rapide, en particulier pour les cas d'utilisation qui ressemblent davantage à des "applications" réelles, où l'utilisateur est censé effectuer de nombreuses interactions sur une longue période de temps.
Dans ces SPA, le "routage" est donc effectué côté client, dans le navigateur.
Tout d'abord, dans notre projet, nous devons installer les routes. Normalement c'est déjà fait, puisque vous avez du le choisir lors de l'installation du projet, dans le cas contraire, il faut l'installer avec la commande suivante :
Si on souhaite ajouter des liens dans notre application, et définir une partie de notre page qui sera remplacée selon l'URL, on doit utiliser la balise <router-link>
(pour les liens) et <router-view>
(pour la partie de la page qui sera remplacée). Si on utilisait une balise <a>
classique, le comportement par défaut du navigateur serait de recharger la page, ce qui n'est pas ce qu'on veut.
Dans le code ci-dessus, on a ajouté deux liens, qui pointent vers les URL /
et /about
. On a également ajouté une balise <router-view>
, qui sera remplacée par le contenu de la page correspondant à l'URL.
Pour que cela fonctionne, il faut ajouter le code suivant dans le fichier src/main.js
(attention certaines parties sont déjà présentes) :
On peut accéder aux paramètres de la route, ou à l'objet router depuis n'importe quel composant, en utilisant les fonctions useRouter
et useRoute
:
Par exemple :
Pour des raisons pratiques et pour éviter de manipuler des URL dans le code, on peut définir des routes nommées.
On peut ensuite utiliser ces routes nommées dans le code :
Cette syntaxe est plus "pratique" pour passer des paramètres. Par ailleurs, dans cette syntaxe les paramètres sont "échapés" pour éviter les caractères interdits.
On peut imbriquer des routes, et ainsi définir des routes "enfant" qui seront affichées dans une route "parent".
Dans cet exemple profile et posts s'afficheront dans la balise <router-view>
de la vue associée au composant User.
Ajoutez un lien et une page permettant d'afficher les détails d'un pays
Ajoutez un menu affichant les 6 continents (Region) et les pays associés
Structurez vos page avec des composants (header, nav, footer, etc...)
Pour chaque fiche pays ajoutez des "onglets" permettant d'organiser l'ensemble des informations du pays (l'organisation est à votre convenance). La page doit contenir au moins 3 "onglets"
Ajoutez une page d'accueil avec la barre de recherche. Les résultats s'afficheront dans une popup... Une popup est une fenetre qui est visible ou non, avec un overlay...
Mettez en place un peu de CSS
Les composants nous permettent de fractionner l'UI en morceaux indépendants et réutilisables, sur lesquels nous pouvons réfléchir de manière isolée. Il est courant pour une application d'être organisée en un arbre de composants imbriqués.
Cette approche est très similaire à celle des éléments HTML, mais Vue.js implémente son propre modèle de composant, nous permettant d'encapsuler du contenu et de la logique au sein de chaque composant. Les composants peuvent être réutilisés dans d'autres composants, et ils peuvent être composés de manière récursive pour créer des applications complexes.
Il existe deux solutions pour construire des composants en Vue.js :
Une approche par Single-File Components (SFC), qui est la solution recommandée par Vue.js et qui consite à créer un fichier .vue pour chaque composant. Ce fichier contient le code HTML, CSS et JavaScript du composant. Nous allons voir cette approche dans la suite de ce cours. Cette solution implique de "compiler" le code du composant, ce qui est fait automatiquement par le CLI de Vue.js.
Un fichier JavaScript qui exporte un objet composant. Nous ne verrons pas cette approche dans ce cours. Cette solution permet un usage sans compilation, mais elle est moins pratique que la solution SFC.
Afin d'utiliser un composant dit enfant dans un composant dit parent, nous devons l'importer. En supposant que nous ayons placé notre composant compteur
dans un fichier nommé ButtonCounter.vue
, le composant apparaîtra comme l'export par défaut du fichier. Pour l'important dans le parent, nous pourrions avoir la syntaxe suivante (nous l'avons déjà rencontré dans les parties précédentes du cours) :
Précisons de nouveau que nous utilisons ici la méthode par "composition" de Vue.js 3, cette solution "simplifie" le code. Pour information avec la solution par "options" de Vue.js 2, nous aurions écrit :
Une fois un composant importé, vous pouvez l'utiliser autant de fois que nécessaire. Chaque composant reste indépendant des autres, et si nous ajoutons 2 composants ButtonCounter
dans le même parent, ils seront indépendants l'un de l'autre et chacun aura ses valeurs propres.
Dans les SFC, il est recommandé d'utiliser des noms de balise en casse Pascal (PascalCase) pour les composants enfants afin de les différencier des éléments HTML natifs. Bien que les noms des balises HTML natifs soient insensibles à la casse, les SFC de Vue sont un format compilé, donc nous pouvons y utiliser des noms de balise sensibles à la casse. Nous pouvons également utiliser /> pour fermer une balise.
Les props sont des attributs personnalisés que nous pouvons passer à nos composants enfants. Ils permettent de passer des données d'un composant parent à un composant enfant.
Imaginons que nous avons une application présentant des articles dans un blog. Nous aurions un composant parent affichant chaque article. Un article serait alors un composant enfant. Nous pourrions avoir une structure de composants comme celle-ci :
Nous aurions ici 4 articles (on pourrait faire une boucle...), mais comment faire pour que chaque article soit différent ? Nous devons définir une "props" pour notre composant enfant Article
, afin qu'il puisse recevoir des données. Nous pouvons définir une prop en utilisant l'attribut props
de notre composant enfant :
Dans ce code, nous définissons qu'il y a une prop title
qui sera passée à notre composant enfant. Nous pouvons ensuite utiliser cette prop dans le template de notre composant enfant. Nous pouvons maintenant passer des données à notre composant enfant :
defineProps
est une macro de compilation qui est seulement accessible à l'intérieur de <script setup>
et ne nécessite pas d'être explicitement importée. Les props déclarées sont automatiquement exposées au template. defineProps
retourne également un objet contenant toutes les propriétés passées au composant, de manière à ce que l'on puisse y accéder en JavaScript si nécessaire :
Un composant peut avoir autant de props que vous voulez, et par défaut, n'importe quelle valeur peut être passée à une prop. Nous pouvons définir des valeurs et un type par défaut pour les props :
En considérant par exemple la liste d'article suivante :
Créez un composant Post
qui affiche le titre et le texte d'un article.
Créez un composant PostList
qui affiche une liste d'articles, en utilisant une boucle pour afficher les Post et passer les éléments.
Remarque : comme nous allons essayer de passer le contenu d'une variable dans une ou plusieurs props, nous devons passer par un v-bind sur les props (comme pour n'importe quel attribut).
Il est possible de passer des props d'un composant à un autre. En reprenant l'exemple ci-dessous, définissez un composant pour un bouton "Lire Plus" (et le composant associé LirePlus) sur votre article qui n'affichera qu'un résumé. Passé depuis le composant Post, l'id de l'article au composant LirePlus.
Les props permettent donc de communiquer du parent vers l'enfant. Mais comment communiquer de l'enfant vers le parent ?
Les composants enfants peuvent émettre des événements, qui peuvent être écoutés par le composant parent.
Reprennons l'exemple de la documentation.
Par exemple, on peut décider d'ajouter une fonctionnalité d'accessibilité permettant d'agrandir le texte des articles du blog, tout en laissant la taille par défaut sur le reste de la page.
Dans le parent, nous développons cette fonctionnalité en ajoutant une variable postFontSize
(qui doit être réactive) :
Qui pourra être utilisée dans le template afin de contrôler la taille de police de tous les articles du blog :
Maintenant ajoutons un bouton dans le template du composant <BlogPost>
:
Pour le moment le bouton ne fait rien. Nous voulons que le clique communique au parent qu'il doit agrandir le texte de tous les articles. Pour résoudre ce problème, les composants fournissent un système personnalisé d'événements. Le parent peut choisir d'écouter n'importe quel événement de l'instance du composant enfant grâce à v-on
ou @
, nous l'avons déjà vue dans une précédente partie :
Ensuite le composant enfant peut émettre lui-même un événement en appelant la méthode intégrée $emit
, et en lui passant le nom de l'événement :
Grâce à l'écouteur @enlarge-text="postFontSize += 0.1"
, le parent va recevoir l'événement et mettre à jour la valeur de postFontSize
.
Intégrez cet exemple à votre projet précédent avec vos articles.
??
Vue.js propose un système de routage nommé , officiellement supporté, qui permet de créer des applications SPA. La documentation officielle se trouve ici : . Tout comme dans les frmameworks back, le système de route est très puissant et permet une contrôle précis de vos URL et des actions associés.
Cette séance est une adaptation/traduction des parties suivantes de la documentation officielle de Vue.js : , et les parties suivantes sur les et les .
https://restcountries.com/#api-endpoints-v3
Exo simple
En utilisant une API de votre choix (suffisament complexe), par exemple :
https://openweathermap.org/api (dans une moindre mesure par rapport aux consignes)
...
Proposez une application interactive permettant de consulter les données. Les critères suivants devront être intégrés
Navigation fluide dans l'ensemble du catalogue
Possibilité d'effectuer une recherche multicritères (cumulables)
Avoir une version "condensée" et une version détaillée
Une mise en page, une ergonomie et une UX travaillée
D'avoir un système de "favori" (stocké en local), permettant de retrouver nos éléments préférés dans un affichage ergonomique.
Repartez d'un projet vide.
En utilisant l'API https://restcountries.com/v3.1/all
Développez un composant permettant d'afficher la fiche d'un pays.
Affichez une page permettant d'afficher tous les pays.
Ajoutez une recherche permettant de filtrer par pays.