Une directive est un attribut "spécial" d'une balise HTML. Il est "spécial" car non conforme au HTML5 (d'où l'apparition d'erreurs lors d'un test de validation du fichier HTML)
Le nom d'une directive commence par v-
. Après son nom
suit le signe =
, suit une chaîne de caractères entourée de guillemets qui
est interprété comme du JavaScript. Cette chaîne de caractères est un nom de variable, de
fonction ou une expression JS évaluable.
Interpolation | Rendu conditionnel | Rendu de liste | Événement | Liaison |
---|---|---|---|---|
v-text | v-show | v-for | v-on:event | v-bind:attr_HTML |
v-html | v-if | v-model | ||
v-pre | v-else-if | |||
v-once | v-else | |||
v-cloak |
v-if
, v-else-if
et v-else
Syntaxe : v-if="expression"
. L'expression est évaluée
à faux si l'évaluation vaut : false, 0, "", null, undefined, NaN
Bonjour
Bonsoir
n < 10
n >=10 et n< 20
n >= 20
Code HTML
<div id="app_if"> <p v-if="isAvant18h">Bonjour</p> <p v-else>Bonsoir</p> <p v-if="n < 10">n < 10</p> <p v-else-if="n >= 10 && n < 20"> n >=10 et n< 20</p> <p v-else>n >= 20</p> </div>
La balise HTML contenant la directive v-else
doit suivre
immédiatement celle contenant la directive v-if
ou
v-else-if
. Cette directive n'attend aucune valeur (donc
v-else=""
= v-else="qqch"
=
v-else
)
La balise HTML contenant la directive v-else-if
doit
suivre immédiatement celle contenant la directive v-if
ou un autre v-else-if
. (Ainsi, la directive v-else-if
est située entre la directive v-if
et la directive v-else
)
Syntaxe : v-else-if="expression"
. L'expression est
évaluée à faux si l'évaluation vaut : false, 0, "", null, undefined,
NaN
Code JS
var app_if = new Vue({ el: '#app_if', data: { isAvant18h:false, n:6 } });
Voir aussi : v-if (guide)
v-on:event
= @event
Le constructeur de la class Vue reçoit un objet qui peut contenir un couple dont la clé est nommée methods. La valeur de cette clé est un objet JS. Cet objet JS contient toutes les fonctions de l'application.
Syntaxe :
nom de méthode : <button v-on:click="faireCeci"></button> évènement dynamique (2.6.0+) : <button v-on:[event]="doThis"></button> ligne d'instruction : <button v-on:click="faireCela('hello', $event)"></button> notation abrégée : <button @click="faireCeci"></button> notation abrégée d'un évènement dynamique (2.6.0+) : <button @[event]="doThis"></button> stoppe la propagation : <button @click.stop="faireCeci"></button> empêche le comportement par défaut : <button @click.prevent="faireCeci"></button> empêche le comportement par défaut sans expression : <form @submit.prevent></form> enchainer les modificateurs : <button @click.stop.prevent="faireCeci"></button> modificateur de touche avec un keyAlias : <input @keyup.enter="onEnter"> modificateur de touche avec un keyCode : <input @keyup.13="onEnter"> l'évènement click sera déclenché une seule fois maximum : <button v-on:click.once="faireCeci"></button> syntaxe objet (2.4.0+) : <button v-on="{ mousedown: faireCeci, mouseup: faireCela }"></button>
{{ message }}
⚠ L'attribut @nom_événement="..."
peut être supprimé
lors d'un nettoyage du code via l'outil Tidy.
Code HTML (avec un nom de fonction)
<div id="app_on"> <p>{{ message }}</p> <p><button v-on:click="reverseMessage">Retourner le texte ci-dessus</button></p> </div>
Code JS
var app_on = new Vue({ el: '#app_on', data: { message: 'Thibaut' }, methods: { reverseMessage: function () { this.message = this.message.split('').reverse().join('') } } })
this
représente l'objet JS (ici, app_on).
Rappel : reverseMessage: function (){...}
peut s'écrire
reverseMessage(){...}
Code HTML (avec une expression)
<div id="app_on2"> <button @click="nb++">Incrémenter</button> {{ nb }} </div>
Code JS
var app_on2 = new Vue({ el: '#app_on2', data: { nb: 0 } })
Les modificateurs
- génériques
- liés à la souris
- liés au clavier
- liés aux touches-système
Modificateurs génériques
- .stop
- .prevent
- .capture
- .self
- .once
- .exact
- .passive
Modificateurs liés à la souris
- .left
- .middle
- .right
Modificateurs liés au clavier (keyAlias)
Ces modificateurs sont utilisés pour déclencher l'événement seulement lorsque la touche correspondante est pressée.
Ces modificateurs correspondent aux touches les plus fréquemment utilisées dans la gestion d'événements.
- .enter
- .tab
- .delete
- .esc
- .space
- .up
- .down
- .left
- .right
Il est également possible de lier une touche à une fonction, via son KeyCode. Toutefois,
l'utilisation des évènements keyCode est déprécié et pourrait ne plus être
supportée dans de futurs navigateurs.
Modificateurs liés aux touches-système
- .ctrl
- .alt
- .shift
- .meta
Va aussi émettre un évènement si les touches Alt et Shift sont pressées : <button v-on:click.ctrl="onClick">A</button> Va émettre un évènement seulement si la touche Ctrl est pressée sans aucune autre touche : <button v-on:click.ctrl.exact="onCtrlClick">A</button> Va émettre un évènement si aucune touche n'est pressée : <button v-on:click.exact="onClick">A</button>
v-on (référence)
Pour plus d'info : sur v-on (guide)
v-show
La directive v-show
permet d'afficher ou cacher le contenu de la
balise dans laquelle elle est incluse. La valeur de cette directive est un booléen, une
variable booléenne ou un nombre entier. Dans ce dernier cas, s'il vaut 0 =>
false, et true dans les autres cas.
Texte visible
Syntaxe : v-show=" true | false | n |
nom_variable/fonction_booléenne"
Code HTML
<div id="app_show"> <p v-show="isVisible">Texte visible</p> <p><button v-on:click="changeEtat">Changer la visibilité</button></p> </div>
Code JS
var app_show = new Vue({ el: '#app_show', data: { isVisible: 2 }, methods: { changeEtat : function(){ this.isVisible = (this.isVisible) ? false : true; } } });
La directive v-show
permet de basculer (toggle) la visibilité
d'un élément en CSS (display). C'est plus performant que v-if
, où
tout l'élément HTML est détruit et recréé à chaque affichage et chaque destruction.
L'état de visibilité est souvent lié à une variable (data:) ou une fonction
(methods:).
Cette directive est plus performante que v-if
. Toutefois, elle ne peut être
utilisée dans un template (d'un composant). Il faut aller utiliser la directive
v-if
.
Mauvais code :
<div v-if="afficher"> ... </div> <div v-else=""> ... </div>
Bon code :
<div show="afficher"> ... </div> <div show="!afficher"> ... </div>
v-pre
La directive v-pre
n'attend aucune valeur. Elle rend le contenu
de la balise statique (et donc aussi les balises enfants). Ainsi, au sein de
l'application, il est possible d'afficher les doubles accolades, ouvrantes et fermantes,
sans que leur contenu puisse être remplacé.
{{ msg }} => msg n'est pas remplacé par le contenu d'une variable, fonction, ...
Code HTML
<div id="app_pre"> <p v-pre>{{ msg }} => msg n'est pas remplacé par le contenu d'une variable, fonction, ...</p> </div>
L'outil Tidy peut donner une valeur vide (="") aux attributs qui n'en ont pas.
Ainsi, pre
sera remplacé par pre=""
Code JS
var app_pre = new Vue({ el: '#app_pre', data: { msg: 'Mon texte' } });
v-for
La directive v-for
permet de répéter des balises HTML (dans la
mémoire du navigateur) sur base d'un tableau de données.
Syntaxe = alias in expression
où alias est l'élément
courant du type de l'expression qui peut être du type : Array | Object |
number | string | Iterable (depuis 2.6)
Le mot-clé in
peut être remplacé par of
.
Expression = number
{{ i }},
Code HTML
<p><span v-for="i in 13">{{ i }}, </span></p>
Ici, l'expression est un nombre entier positif supérieur à zéro et vaut 13. C'est la limite supérieure (comprise). Et, l'alias vaut i. C'est l'élément courant, initialisé à 1. (Et, le pas (step) vaut 1)
Il n'est pas possible de modifier la borne inférieure, ni le pas (step). Ils valent toujours 1. En réalité, lorsque l'expression est un nombre. Cela indique le nombre de fois que l'élément est répété.
Expression = string
{{ lettre }},
Code HTML
<p><span v-for="lettre in 'Jean Pierre'">{{ lettre }}, </span></p>
Ici, l'expression est une string qui est traitée comme un tableau de caractères.
Expression = array
En pratique, la directive v-for
sert à parcourir un tableau :
- de valeurs numériques
- de caractères ou de strings
- d'objets (ayant un ou plusieurs couples clé:valeur)
L'index peut être utilisé avec tout type de tableau.
Tableau de valeurs numériques
{{ i }},
Code HTML
<p><span v-for="i in [7,8,9,10,11,12,13]">{{ i }}, </span></p>
ligne in tableau
. Le terme à droite de cette
expression est le nom d'une variable représentant le tableau qui sera parcouru. Le
terme à gauche de cette expression est le nom d'une variable représentant un élément du
tableau. Le terme du milieu est le mot-clé in
. Le
tableau peut contenir des valeurs ou des objets.
Tableau de caractères
{{ lettre }}
Code HTML
<p><span v-for="lettre in ['T','h','i','b','a','u','t']">{{ lettre }}</span></p>
Tableau de strings
- {{ ligne }}
<ol> <li v-for="ligne in tableau">{{ ligne }}</li> </ol>
data: { tableau: [ 'Apprendre le HTML', 'Étudier le CSS', "Coder en JavaScript" ] }
Tableau de strings (avec index)
- {{ numLigne }} => {{ ligne }}
<ul> <li v-for="(ligne, numLigne) in tableau" v-on:click="getAction(numLigne)"> {{ numLigne }} => {{ ligne }}</li> </ul>
methods: { getAction(index) { alert("Mon choix : " + this.tableau[index]); } }
Lorsque le terme de gauche est entouré de parenthèses, il doit être composé de deux noms de variables séparées par une virgule. Le terme de droite représente alors l'index du tableau (qui commence toujours à 0).
Tableau d'objets (contenant un couple cle:valeur)
- {{ ligne.cle }}
<ul> <li v-for="ligne in tableau2">{{ ligne.cle }}</li> </ul>
data: { tableau2: [ { cle: 'Étudier' }, { cle: 'Apprendre' }, { cle: "Comprendre" } ] }
Tableau d'objets (contenant plusieurs couples cle:valeur)
{{ personne.prenom }} | {{ personne.nom }} |
<table> <tr v-for="personne in personnes"> <td>{{ personne.prenom }}</td> <td>{{ personne.nom }}</td> </tr> </table>
data: { personnes: [ {nom: "Durand", prenom: "Jacques"}, {nom: "Dupont", prenom: "Thibaut"}, {nom: "Martin", prenom: "Denis"}, } }
Template v-for
De la même manière qu'avec v-if, vous pouvez également utiliser la balise <template> avec v-for pour faire le rendu d'une structure contenant de multiples balises.
<ul> <template v-for="item in items"> <li>{{ item.msg }}</li> <li class="divider" role="presentation"></li> </template> </ul>
v-for avec v-if
il n'est pas recommandé d'utiliser v-if
et v-for
ensemble.
Quand elle est utilisée conjointement avec v-if
, v-for
a une
plus grande priorité que v-if
.
Voir aussi : v-for (guide), Affichage de résultats filtrés/triés
v-bind:attr_HTML
La directive v-bind
permet de lier la valeur d'un attribut HTML à la
valeur d'une donnée (data).
Usuellement, dans une syntaxe telle que
v-bind:attr_HTML="expression"
, expression est le nom d'une
propriété réactive (définie dans data:)
De plus, quand v-bind
est utilisé avec les attributs liés à
l'apparence : class="" et style="" l'expression peut évaluer des
objets ou des tableaux.
Ci-dessous, toutes les syntaxes possibles :
lie un attribut (ici, src) : <img v-bind:src="imageSrc"> nom d'attribut dynamique (2.6.0+) : <button v-bind:[key]="value"></button> notation abrégée : <img :src="imageSrc"> notation abrégée d'un nom d'attribut dynamique (2.6.0+) : <button :[key]="value"></button> avec de la concaténation de chaînes de caractères : <img :src="'/path/to/images/' + fileName"> liaison de classes : <div :class="{ red: isRed }"></div> <div :class="[classA, classB]"></div> <div :class="[classA, { classB: isB, classC: isC }]"></div> liaison de styles : <div :style="{ fontSize: size + 'px' }"></div> <div :style="[styleObjectA, styleObjectB]"></div> lie un objet d'attributs : <div v-bind="{ id: uneProp, 'autre-attr': uneAutreProp }"></div> lie un attribut du DOM avec le modificateur prop : <div v-bind:text-content.prop="text"></div> liaison de prop. "prop" doit être déclaré dans mon-composant. : <mon-composant :prop="uneValeur"></mon-composant> transmet les props parentes à un composant enfant : <composant-enfant v-bind="$props"></composant-enfant> XLink : <svg><a :xlink:special="foo"></a></svg>
Code HTML
<div id="app_bind"> <span v-bind:title="message"> Passez votre souris sur moi pendant quelques secondes pour voir mon titre lié dynamiquement ! </span> </div>
Code JS
var app_bind = new Vue({ el: '#app_bind', data: { message: 'Vous avez affiché cette page le ' + new Date().toLocaleString() } });
Usuellement, dans une syntaxe telle que
v-bind:attr_HTML="expression"
, expression est le nom d'une
propriété réactive (définie dans data:)
De plus, quand v-bind
est utilisé avec les attributs HTML class=""
et/ou style="" l'expression peut évaluer des objets ou des tableaux.
Mais, quand v-bind
est utilisé avec l'attribut HTML style=""
- l'expression ne peut pas être un nom de propriété réactive, ni une string.
-
Recommandation :
Code HTML
<div v-bind:style="styleObject"></div>
Code JS
data: { styleObject: { color: 'red', fontSize: '13px' } }
La directive v-bind:attr_HTML="nom_data"
ressemble à la
fonction JS setAttribute()
.
Voir aussi : Liaison de classes HTML, Liaison de styles HTML
v-model
Une application web est souvent liée à un formulaire.
La directive, bi-directionnelle, v-model
est liée aux seules
balises - <input>, <select> et <textarea> - et permet de
lier la valeur de l'attribut HTML value à une donnée du modèle (data:). Ainsi,
tout changement dans le contrôle est répercuté dans le modèle et comme le modèle change,
la vue change.
v-model
ne prend pas en compte la valeur initiale des attributs value,
checked ou selected fournis par un champ. La valeur initiale doit être
déclarée dans l'option data.
- Les éléments correspondant aux balises input type="text" et textarea utilisent la propriété value et évènement input; Les éléments correspondant aux balises input type="checkbox" et input type="radio" utilisent la propriété checked et change; Les éléments correspondant aux balises select utilisent value comme une prop et l'évènement change.
L'interpolation sur les zones de texte (<textarea>{{text}}</textarea>
)
ne fonctionnera pas. Utilisez v-model
à la place.
Ceci facilite grandement la validation JS du formulaire avant l'envoi des données au serveur.
Pour faciliter la compréhension des codes ci-dessous, les attribut HTML name et
value, nécessaires lors de l'envoi de données au serveur, ne sont pas présents.
Cependant, ils sont nécessaires pour le contrôle du type="radio"
(car il est
obligatoire pour former un groupe).
Les modificateurs :
-
.lazy : écoute les évènements change au lieu de
input
Se déclenche au changement de focus. - .number : convertit les chaînes de chiffres en nombres
- .trim : retire les blancs autour de la chaîne de caractères
Avec la balise <input>
<input type="text" />
Code HTML
<form id="app5_trim"> <p><input v-model="message" /></p> <pre>+++{{ message }}+++</pre> <p><input v-model.trim="message2" /> (.trim)</p> <pre>+++{{ message2 }}+++</pre> <p><input v-model.lazy="message3" /> (.lazy)</p> <pre>+++{{ message3 }}+++</pre><p> <input v-model.trim.lazy="message4" /> (.trim.lazy) = recommandé</p> <pre>+++{{ message4 }}+++</pre> </form>
Code JS
var app5_trim = new Vue({ el: '#app5_trim', data: { message: 'Bonjour, Thibaut !', message2: 'Bonjour, Léon !', message3: 'Bonjour, Bernard !', message4: 'Bonjour, Marc !' } });
<input type="number" />
La valeur renvoyée d'un champ d'un formulaire est toujours une string (jamais un
nombre, une date, un montant, ...).
L'attribut type="number"
permet de limiter les caractères à ceux
nécessaires à la formation d'un nombre. Selon la configuration du navigateur, il faudra
utiliser le point ou la virgule décimale.
Le modificateur .number est alors très utile.
Code HTML
<p> <input type="number" v-model="nombre" /> +2 = <span v-text="result"></span> </p> <p> <input type="number" v-model.number.lazy="nombre2" /> +2 = <span v-text="result2"></span> (.number.lazy) </p>
Code JS
var app5_number = new Vue({ el: '#app5_number', data: { nombre: 1, nombre2: 1 }, computed:{ result(){ return this.nombre+2 }, result2(){ return this.nombre2+2 } } });
<input type="radio" />
Ce qui est retourné lors du clic est la valeur de l'attribut value.
Code HTML
<form id="app5b" name="app5b"> <p> <label> <input type="radio" name="sex" value="mâle" v-model="sexe" /> Sexe fort </label> </p> <p> <label> <input type="radio" name="sex" value="femelle" v-model="sexe" /> Sexe faible </label> </p> <p v-show="sexe.length"> Vous avez choisi "{{sexe}}". </p> </form>
Grâce à la directive v-show
, la phrase indiquant le choix n'est pas
affichée tant que le choix n'a pas été fait.
Code JS
var app5b = new Vue({ el: '#app5b', data: { sexe: '' } });
En attribuant, dans le code JS, une valeur par défaut (initiale) ne correspondant pas à
celle d'un des attributs HTML value), il n'y a pas de choix par défaut, même si un
choix par défaut est donné par du code HTML, checked="checked"
. En effet, le
navigateur analyse, dans l'ordre, le code HTML, puis le code CSS et enfin le code JS. Le
code JS a donc le dernier mot.
<input type="checkbox" />
Code HTML
<form id="app5c" name="app5c"> <label> <input type="checkbox" v-model="isChecked" /> Je suis <strong>{{ isChecked }}</strong> </label> </form>
Code JS
var app5c = new Vue({ el: '#app5c', data: { isChecked: false } });
Avec la balise <select>
<select> : choix unique
Code HTML
<form id="app5d"> <p> <select v-model="choix"> <option> </option> <option>Choix 1</option> <option>Choix 2</option> <option>Choix 3</option> </select> </p> <p v-show="choix.length"> Vous avez choisi : "{{ choix }}" </p> </form>
Code JS
var app5d = new Vue({ el: '#app5d', data: { choix: [] } });
<select> : choix multiple
Rappel : Pour effectuer un choix multiple, il faut maintenir la touche CTRL enfoncée.
Code HTML
<form id="app5d2"> <p> <select v-model="choix" multiple="multiple"> <option> </option> <option>Choix 1</option> <option>Choix 2</option> <option>Choix 3</option> </select> </p> <p v-show="choix.length"> Vous avez choisi : "{{ choix }}" </p> </form>
Code JS
var app5d2 = new Vue({ el: '#app5d2', data: { choix: [] } });
Exemple : Remplir une liste déroulante
Code HTML
<form id="app5d3"> <p> <select v-model="choix" multiple="multiple"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> </p> <p v-show="choix.length"> Vous avez choisi : "{{ choix }}" </p> </form>
Code JS
var app5d3 = new Vue({ el: '#app5d3', data: { choix: '', options:[ {text:'', value:0}, {text:'Choix 1',value:1}, {text:'Choix 2',value:2}, {text:'Choix 3',value:3} ] } });
Pour en finir avec les directives restantes, toutes d'interpolation :
v-text
, v-html
, v-pre
, v-cloak
et
v-once
.
v-text
Les mustache permettent d'insérer du contenu dans le contenu d'une balise. Cette directive permet de remplacer le contenu de la balise.
Le contenu d'une balise est ce qui se trouve entre la balise ouvrante et la balise fermante.
Code HTML
<div id="app_text"> <p v-text="texte"></p> </div>
Code JS
var app_text = new Vue({ el: '#app_text', data: { message: 'Mon texte' } }); app_text.message = 'Mon autre texte'; /* = app_text.$data.message */
Un objet JS de type Vue dispose de clés. Le caractère $ précède le nom de ces clés,
lorsqu'elles sont utilisées hors du constructeur de cette Vue.
$el, $data, $props, $methods, ... app7.$data.message
La directive v-text
ressemble à la propriété JS
.textContent
v-html
La directive v-html
ressemble à la propriété JS
.innerHTML
. Attention aux
attaques XSS ! Utilisez v-html uniquement avec du contenu de confiance et jamais
avec du contenu fourni par les utilisateurs.
Code HTML
<div id="app_html"> <p v-html="texte"></p> </div>
Code JS
var app_html = new Vue({ el: '#app_html', data: { message: '<u>Mon texte</u>' } });
v-once
La directive v-once
n'attend aucune valeur. Elle rend le
contenu de la balise modifiable qu'une seule fois (et donc aussi les balises enfants).
Code HTML
<div id="app_once"> <button> v-on="nb++">Bouton cliqué : {{ nb }} fois</button> </div>
L'outil Tidy peut donner une valeur vide (="") aux attributs qui n'en ont pas.
Ainsi, pre
sera remplacé par pre=""
Code JS
var app_once = new Vue({ el: '#app_once', data: { nb: 0 } });
v-cloak
Cette directive restera sur l'élément jusqu'à ce que l'instance de Vue associée ait fini sa compilation. Combiné avec des règles CSS telles que [v-cloak] { display: none }, cette directive peut être utilisée pour cacher des liaisons moustaches encore non compilées jusqu'à ce que l'instance de Vue soit prête.
L'outil Tidy peut donner une valeur vide (="") aux attributs qui n'en ont pas.
Ainsi, pre
sera remplacé par pre=""
Directives personnalisées
Il est possible de créer ses propres directives.
filters:
L'option filters:
permet de stocker des filtres qui peuvent être utilisés
pour appliquer des formatages de textes courants. Les filtres sont utilisables à deux
endroits : les interpolations à moustaches et les expressions de
v-bind.
Dans les moustaches : {{ message | capitalize }} Dans les v-bind : <div v-bind:id="rawId | formatId"></div>