1°/ Les bases de Vuejs
1.1°/ Inclure vuejs dans une page
- Il existe des environnements de développement pour vuejs (par ex, vue-cli) permettant de construire la partie front-end d'une application Web en se basant sur vuejs.
- Ils permettent généralement de créer un projet sous la forme d'une arborescence de fichiers, à compléter par le développeur.
- Mais pour maîtriser ces environnements, il faut d'abord comprendre les mécanismes de Vuejs.
- Pour cela, une simple page HTML plus un ou deux fichiers javascript sont suffisants.
- En effet, il suffit d'inclure le "package" vuejs en entête de la page HTML, puis de créer un objet "application vuejs" dans un fichier javascript. Le contenu de cet objet, plus des directives spéciales utilisées dans le HTML vont permettent de rendre la page dynamique.
Démonstration (NB : toutes les démos ont été testées sous chrome) :
- créer un fichier index-01.js et copier/coller dedans :
1 2 3 4 5 6 |
var app = new Vue({ el: '#mydiv', data: { myvalue: 5 } }) |
- créer un fichier exe-01.html et copier/coller dedans :
Remarques :
- l'URL permet d'inclure dans la age tout le code javascript représentant la "machinerie" vuejs.
- l'instanciation d'un objet application vuejs se fait grâce à la classe Vue. Généralement, on crée une seul instance pour toute l'application web (surtout dans les cas simples). Mais il est tout à fait possible de créer plusieurs instances de Vue et même de les faire cohabiter au sein d'une même page HTML. Ce n'est pas forcément conseillé si elles doivent interagir.
- l'attribut el de l'objet app doit corresponder à l'attribut id de l'élément HTML sur lequel on veut interférer grâce à vuejs. Si on veut une page enitèrement dynamique, il faut que cet élément englobe tout le HTML de <body>, comme c'est le cas dans l'exemple.
- l'inclusion de index-01.js doit obligatoirement être fait après cet élément englobant. Conformément aux remarques du TD n°1, il faut que les éléments du DOM existent pour que app puisse y accéder.
- l'attribut data et les {{ }} sont abordés juste après.
1.2°/ Texte dynamique dans <p>, <span>, <li>, ...
Démonstration :
- Toute la magie de vuejs vient du fait que l'on peut avec des syntaxes très simples rendre le DOM et donc le rendu visuel dynamique, comme on peut le faire avec du javascript natif.
- La première étape consiste à ajouter des attributs à l'objet data dans notre application. On donne un nom et une valeur à ces attributs. On peut ensuite réutiliser ces noms dans des directives vuejs pour faire de l'affichage dynamique.
- En effet, vuejs va observer l'état de ces attributs, et dès que leur valeur change, les éléments du DOM qui les utilisent vont être rafrachis. Plus besoin d'écrire du javascript pour faire cette mise à jour !
- Le cas le plus simple est de pouvoir personnaliser du texte affiché au sein d'une balise de type <p>, <span>, <li> .etc. Dans ce cas, on ajoute dans data un couple nom_attribut : valeur et on utilise la syntaxe {{ nom_attribut }} dans le HTML.
- C'est ce principe qui est utilisé dans la première manipulation.
- On peut maintenant vérifier que l'affichage est bien dynamique.
Démonstration :
- revenir dans le navigateur et ouvrir l'inspecteur.
- dans la console, taper app.$data.myvalue = 10 (NB : on remarque que l'on accède pas à l'atribut data directement, mais grâce à $data.)
- la valeur affichée dans la page change immédiatement à 10.
- dans la console, taper app.myvalue = 20. La valeur change de nouveau.
- on remarque que vuejs "duplique" les attributs de data pour qu'ils soient accessibles directement via app. C'est pratique mais ATTENTION aux éventuels doublons.
- dans la console, taper app.myvalue = '<h1>Salut</h1>'
- Argh, l'interprétation du HTML n'est pas faite.
- De base, {{ }} ne permet pas d'ajouter des éléments au DOM. Donc s'il contient du HTML, c'est le code qui est affiché, pas son interprétation.
- Pour que la valeur soit interpétée, il faut utiliser la directive v-html du vuejs, d'une façon qui peut sembler étrange.
Démonstration :
- dans exe-01.html, modifiez la définition de la balise <p> en remplaçant par :
- rechargez la page puis dans la console, tapez : app.myvalue = '<h1>Salut</h1>
- cette fois, la valeur est bien interprétée comme du HTML et apparaît quand bien même <p> ne contient pas de texte => un peu magique tout ça non ?
Remarques globales :
- ATTENTION ! Ne JAMAIS utiliser v-html sur une variable contenant une valeur fixée par une entrée utilisateur. C'est une énorme faille. Par exemple, cela permet d'injecter du javascript.
- les {{ }} sont appelées moustaches.
- on peut mettre entre moustache n'importe quelle variable accessible via data mais jamais des variables définies en dehors. En revanche, les attributs de data peuvent parfaitement être initialisés grâce à des variables externes.
Démonstation :
- modifier index-01.js pour qu'il contienne :
1 2 3 4 5 6 7 8 9 |
var obj = { type:"rect", coords:{x:1, y:2} } var app = new Vue({ el: '#mydiv', data: { myvalue : 5, myobj : obj } }) |
- Modifier exe-01.html pour ajouter 3 lignes au début de la balise <div> :
- La première ligne n'affiche rien. C'est normal car obj n'est pas "observé" par vuejs. Donc, elle provoque un warning dans la console : [Vue warn]: Property or method "obj" is not defined on the instance ...
- La deuxième ligne affiche la valeur de myobj stringifiée. Comme myobj est le même objet que obj, on obtient : { "type": "rect", "coords": { "x": 1, "y": 2 } }
- La troisième ligne affiche 1.
- myobj étant observée par vuejs, tout changement de sa valeur va changer le visuel. Mais comme myobj est un alias de obj, que l'on change myobj ou obj, c'est pareil.
- par exemple, taper dans la console : app.myobj.type = 'circ'. La chaîne stringifiée change.
- taper obj.coords.x = 5 puis taper app.myobj.coords.x = 10. Dans les deux cas, la valeur change. Magique !
1.3°/ Texte dynamique dans les balises à attribut value (par ex <input>)
- Certaines balises ne suivent pas le principe de balise ouvrante/fermante, comme <p> et </p>.
- Elles n'ont pas de notation fermante. Par exemple <input>.
- Pourtant, ces balises servent potentiellement à afficher du texte, grâce à leur atribut value. Exemple :
- Le champ de saisie texte va être affiché avec comme valeur courante "init_value".
- Pour que cette valeur provienne d'un des attributs de data, il faut utiliser la directive v-bind. Comme son nom l'indique, elle permet de relier la valeur d'un attribut de balise, à la valeur d'un attribut de data.
Démonstration :
- créer un fichier model.js et copier/coller dedans :
1 2 |
var item1 = {name:'sword', cat:'weapon', price:100}; var item2 = {name:'apple', cat:'food', price:2}; |
- créer un fichier index-02.js et copier/coller dedans :
1 2 3 4 5 6 |
var app = new Vue({ el: '#mydiv', data: { item:item1 } }) |
- créer un fichier exe-02.html et copier/coller dedans :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<html> <head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="model.js"></script> </head> <body> <div id="mydiv"> <p>chosen item price: {{item.price}}</p> <input v-bind:value="item.price"> </div> <script src="index-02.js"></script> </body> </html> |
- on constate que c'est bien le prix de item1 qui s'affiche.
- ouvrir l'inspecteur.
- taper dans la console : app.item = item2. Comme item est observée et change, les éléments HTML où item est utilisé dans une directive vuejs sont rafraichis.
- taper dans la console : item2.price = 500. Le prix change à l'écran.
- taper dans la console : item1.price = 25. Rien ne change. Normal, item = item2.
- taper dans la console : app.item = item1. Le prix affiché est bien 25.
Remarques :
- v-bind peut être utilisé sur n'importe quel attribut d'un balise HTML. Par exemple, on peut l'utiliser sur les attributs style, class pour rendre dynamique le visuel, ou bien sur des attributs spécifiques à a balsie, comme par exemple l'attribut readonly d'un champ de saisie <input>.
- Si la valeur du champ de saisie change, il serait pratique que la valeur de l'attribut de data qui sert à alimenter le champ de saisie change en retour. Cette relation bidirectionnelle peut être mise ne place graĉe à la directive v-model.
- Ces points serotn abordés lors du TD n°3.