Client Web avec Vue.js

Vue.js est un framework Javascript permettant de définir, entre autres, des interfaces client Web en mode SPA (Single Page Application). Ce type de fonctionnement définit une page unique dont les différents composants sont affichés ou masqués en fonction des interactions avec l'utilisateur, sans qu'il soit nécessaire de recharger la page.

Vue.js peut se programmer de différentes manières. La plus pratique au niveau codage est d'utiliser un langage de script dédié et une définition des composants dans plusieurs fichiers séparés mais qui nécessite une pré-compilation et donc des outils supplémentaires. La plus simple d'utilisation est d'importer dans une page HTML la libraire Javascript de Vue et d'utiliser ses fonctionnalités directement dans la page HTML. C'est cette deuxième option que nous allons utiliser dans ce TP.

Pour l'ajout direct de fonctionnalités Vue dans une page HTML, on peut utiliser deux API (deux syntaxes différentes) : Options ou Composition. La première est plus simple d'utilisation et la seconde plus adaptée à des pages complexes mais requiert plus de compréhension des détails du fonctionnement de Vue. Les exemples présentés ci-dessous seront écrits avec l'API Options. On peut indifféremment implémenter un même client avec l'une ou l'autre des API.

La version de Vue.js utilisée ici est la version 3.

Vue par quelques exemples

Mise en place de l'environnement des exemples

Dans les exemples de cette section, nous allons interroger le serveur Tomcat qui fera une requête sur le serveur MongoDB pour récupérer l'ensemble des sportifs de votre base de données du TP précédent. Ensuite, ces sportifs seront affichés dans une page HTML en utilisant les données réactives de Vue.

Pour commencer, vous allez créer dans votre application Web Java, une nouvelle Servlet intitulée "AccesMongo" dont voici le code : AccesMongo.java. Modifiez la ligne 25 pour avoir la bonne URL du serveur MongoDB et la ligne 28 pour utiliser le bon nom de votre base de données.

Données réactives

Une des fonctionnalités principales de Vue est de pouvoir définir des données dites réactives. Les données sont définies dans un composant Vue, elles sont affichées dans le HTML de la page via une syntaxe dite à moustaches : {{ maDonnee }}. Ensuite, quand du code Javascript modifie une donnée, elle est automatiquement mise à jour dans le HTML. De manière symétrique, si des entrées d'un formulaire sont liées à des données du composant, quand l'utilisateur modifie des champs, les données du composant sont modifiées en conséquence.

Téléchargez le fichier sportifs-vue.html. Modifiez la ligne 51 pour changer le nom du projet de votre application Web (ici "TestWeb") de façon à ce que la requête HTTP corresponde bien à votre Servlet "AccesMongo". Ensuite, vous avez simplement à ouvrir le fichier dans un navigateur Web et la liste des sportifs doit s'afficher dans le navigateur.

Voici l'image du code de la page avec les numéros de ligne :

Le code de sportifs-vue.html

Explications sur le code :

Liens avec formulaires

La page formulaire-vue.html fait le lien entre les données d'un composant Vue et les entrées d'un formulaire (listes, zones de texte ...) en utilisant la directive v-model. Voici le code de la page HTML :

Formulaire avec Vue

Pensez à modifier la ligne 46 pour avoir la bonne URL de la requête sur le serveur Tomcat, comme pour l'exemple précédent.

Composants

Dans les deux exemples précédents, il y a un seul composant Vue par page, que l'on appelle composant racine. Vue permet d'instancier plusieurs composants dans la même page en plus du composant racine. Ces composants sont similaires à ceux déjà vus avec en plus un template HTML : quand le composant sera instancié, il affichera un bout de code HTML. L'usage le plus pratique est de définir chaque composant dans un fichier spécifique, en suivant le modèle SFC (Single-File Component). La limite est qu'il faut ensuite compiler les composants pour former une seule page et cela nécessite des outils spécifiques. Ici nous allons suivre notre logique d'utilisation directe de Vue sans outil et donc définir tous les composants dans un seul fichier HTML.

Une fois le composant créé, on l'utilisera comme une nouvelle balise HTML qui à chaque usage instanciera un composant. On aura alors la syntaxe suivante : <mon-composant propriete="..." @unevenement="...">contenu falcultatif</mon-composant>. Un composant définit plusieurs éléments :

Téléchargez le fichier composants-vue.html. Cette page va afficher la liste des sportifs comme dans le premier exemple mais cette fois en utilisant une instance de composant dédiée par sportif. Modifiez comme précédemment la ligne 32 pour avoir le bon lien vers la Servlet de votre application Web.

Le composant racine est le même que dans le premier exemple, il s'appelle "ChargerSportif" et est défini à partir de la ligne 23. Il définit une donnée "sportifs" qui va contenir tous les sportifs de la base de données via une requête sur le serveur Tomcat. Il définit une donnée "monRoger" qui est un sportif défini en dur et une donnée "leSelectionne" qui contiendra le nom du dernier sportif sélectionné.

La balise main au début de la page contient le code HTML principal de la page :

Le code du main

Voici le code du composant "AfficherSportif" qui est instancié en plusieurs exemplaires aux lignes 14 et 15 du code HTML principal de la page :

Le code du composant AfficherSportif

Enfin, pour lancer l'application, il faut associer les composants avec leurs balises comme ceci :

Initialisation des
composants

Pour aller plus loin

Les exemples ci-dessus présentent les principales fonctionnalités de Vue mais ce framework permet de faire beaucoup d'autres choses.

Nous n'avons par exemple pas abordé la mise en forme dynamique avec la possibilité de changer facilement par des directives Vue le style CSS d'éléments HTML.

Nous avons vu la communication basique entre composants : un parent peut passer des paramètres à un enfant et un enfant peut envoyer un événement à son parent. Mais il peut être utile que des composants qui ne sont pas directement parent/enfant puissent s'envoyer des événements. Pour cela, il faudra utiliser des "routeurs". On peut cependant facilement envoyer des données d'un parent vers sa descendance plus profonde que le premier enfant via les directives "Provide / Inject".

Pour l'identification des éléments HTML dans la page, la directive ref est plus pratique que d'utiliser l'identifiant HTML id. On peut mettre un identifiant de la même façon comme par exemple <div ref="monDiv"> et ensuite, on peut facilement récupérer la référence de l'élément dans une méthode du composant via this.$refs.monDiv

Enfin, comme précisé ci-dessus, nous avons ici utilisé l'écriture de composants Vue au sein d'une seule page HTML qui offre l'avantage de ne nécessiter aucune installation mais rend le code plus difficile à maintenir. Il existe des outils qui permettent de définir un projet Vue avec des fichiers bien séparés que l'on compilera ensuite ensemble, comme par exemple Vite ou Vue CLI.

Au niveau outil, l'éditeur dont sont tirés les screenshots de code ci-dessus est Visual Studio Code avec l'extension Volar.

Pour aller plus loin dans l'étude des fonctionnalités de Vue, voici quelques liens :

Travail à réaliser

Téléchargez les 3 exemples ci-dessus, testez les et prenez le temps de comprendre leur fonctionnement.

Ensuite, modifiez ou créez des pages HTML utilisant Vue pour accéder aux données de vos bases en envoyant des requêtes sur le serveur Tomcat.

Dans les exemples, la commande Javascript fetch est utilisée pour faire une requête HTTP sur le serveur Tomcat. Elle est plus simple à utiliser que les requêtes AJAX avec XMLHttpRequest. Vous trouverez sur cette page une documentation sur cette commande pour savoir notamment comment rajouter des paramètres à la requête envoyée au serveur HTTP : https://developer.mozilla.org/fr/docs/Web/API/Fetch_API/Using_Fetch.

Alternative au fetch pour le chargement des sportifs

Si vous n'arrivez pas à faire fonctionner ou si vous n'avez pas fini la partie d'accès à MongoBD via le serveur Tomcat, le fetch ne chargera rien dans la données "sportifs" des 3 exemples et vos pages n'afficheront rien ou presque. Dans ce cas, supprimez dans les 3 exemples, les 4 lignes de code du champ created() et dans la section data, remplissez en dur le contenu de "sportifs" comme ceci :

data() {
   return {
      sportifs: [{"_id": 1, "prenom": "Roger", "nom": "Blanchard", "age": 57, "genre": "homme", "adresse": {"rue": "12 rue de Siam", "ville": "Brest", "codePostal": 29200}, "disciplines": ["100m", "200m", "descente"], "marie": true},{"_id": 2, "prenom": "Simone", "nom": "Blanchard", "age": 52, "genre": "femme", "adresse": {"rue": "12 rue de Siam", "ville": "Brest", "codePostal": 29200}, "disciplines": ["200m 4 nages", "100m libre"], "marie": true},{"_id": 3, "prenom": "Gérard", "nom": "Lebreton", "age": 24, "genre": "homme", "adresse": {"rue": "20 rue Saint-Michel", "ville": "Rennes", "codePostal": 35000}, "disciplines": ["marathon", "slalom", "géant", "100m libre", "descente", "100m"], "lastModified": {"$date": "2023-01-21T21:32:35.774Z"}},{"_id": 4, "prenom": "Régine", "nom": "Mouvier", "age": 41, "genre": "femme", "adresse": {"rue": "153 rue Jean Jaures", "ville": "Brest", "codePostal": 29200}, "disciplines": ["descente", "100m libre", "marathon", "marathon", "géant"]},{"_id": 12, "nom": "Legrand", "prenom": "Saturnin", "age": 23, "genre": "homme", "adresse": {"rue": "12 rue de Navarre", "ville": "Pau", "codePostal": 64000}}],
      ...


Eric Cariou, dernière modification : 12/02/23