Guide
Essentiel
- Installation
- Introduction
- Instance de Vue
- Syntaxe de template
- Propriétés calculées et observateurs
- Liaisons de classes et de styles
- Rendu conditionnel
- Rendu de liste
- Gestion des évènements
- Liaisons sur les champs de formulaire
- Composants
Composants en détail
- Création de composants
- Props
- Évènements personnalisés
- Slots
- Composants dynamiques et asynchrones
- Gérer les cas limites
Transitions & animation
- Transitions d'entrée, de sortie et de liste
- Transitions d'état
Réutilisabilité & composition
- Mixins
- Directives personnalisées
- Fonctions de rendu et JSX
- Plugins
- Filtres
Outils
- Composants monofichiers
- Testing
- Support de TypeScript
- Déploiement en production
Évolutions
- Routage
- Gestion de l'état
- Rendu côté serveur
- Security
Mécanismes
- Réactivité en détail
Migration
- Migration depuis Vue 1.x
- Migration depuis Vue Router 0.7.x
- Migration depuis Vuex 0.6.x à 1.0
Meta
- Comparaison avec les autres frameworks
- Rejoignez la communauté Vue.js !
- Rencontrer l'équipe
You’re browsing the documentation for v2.x and earlier. For v3.x, click here.
Fonctions de rendu et JSX
Bases
Vue vous recommande l’utilisation de templates pour construire votre HTML dans la grande majorité des cas. Il y a cependant des situations où vous aurez réellement besoin de toute la puissance programmatique de JavaScript. C’est là que vous pouvez utiliser les fonctions de rendu, une alternative aux templates qui est plus proche du compilateur.
Examinons un exemple simple où une fonction render
serait plus pratique. Imaginons que nous souhaitons générer des titres avec une ancre :
|
Pour le HTML ci-dessus, vous décidez d’utiliser cette interface de composant :
|
Quand vous commencez avec un composant se basant sur la prop level
pour simplement générer des niveaux de titre, vous arrivez rapidement à cela :
|
|
Ce template ne semble pas génial. Il n’est pas uniquement verbeux, il duplique <slot></slot>
dans tous les niveaux de titre et nous allons devoir refaire la même chose quand nous ajouterons l’élément ancre.
Alors que les templates fonctionnent bien pour la plupart des composants, il est clair que celui-là n’est pas l’un d’entre eux. Aussi essayons de le réécrire avec une fonction render
:
|
C’est bien plus simple ! Le code est plus court mais demande une plus grande familiarité avec les propriétés d’une instance de Vue. Dans ce cas, vous devez savoir que lorsque vous passez des enfants sans une directive v-slot
dans un composant, comme le Hello world !
à l’intérieur de anchored-heading
, ces enfants sont stockés dans l’instance du composant via la propriété $slots.default
. Si vous ne l’avez pas encore fait, il est recommandé d’en lire plus sur les propriétés d’instance de l’API avant d’entrer plus en profondeur dans les fonctions de rendu.
Nœuds, arbres, et DOM virtuel
Avant de rentrer en profondeur dans les fonctions de rendu, il est important de savoir comment un navigateur fonctionne. Prenons cet HTML comme exemple :
|
Quand votre navigateur lit ce code, il construit un arbre de nœud de DOM pour l’aider à garder une trace de tout, comme vous ferriez un arbre généalogique pour garder une trace de votre famille étendue.
L’arbre des nœuds du DOM pour le HTML ci-dessus ressemblerait à cela :
Chaque élément est un nœud. Chaque morceau de texte est un nœud. Même les commentaires sont des nœuds ! Un nœud est juste un morceau de la page. Et comme dans un arbre généalogique, chaque nœud peut avoir des enfants (c.-à-d. que chaque morceau peut contenir d’autres morceaux).
Mettre à jour tous ces nœuds efficacement peut être difficile, mais heureusement, vous n’avez jamais à le faire manuellement. Vous avez juste à dire à Vue quel HTML vous voulez pour votre page dans un template :
|
Ou quelle fonction de rendu :
|
Et dans les deux cas, Vue va automatiquement garder la page à jour, même quand blogTitle
change.
DOM virtuel
Vue arrive à cela grâce à la construction d’un DOM virtuel pour garder les traces des changements qui doivent être faits sur le vrai DOM. Prêtons attention à cette ligne :
|
Qu’est-ce que createElement
retourne exactement ? Ce n’est pas réellement un vrai élément de DOM. Cela pourrait être nommé plus justement createNodeDescription
, car il contient des informations décrivant à Vue quelle sorte de rendu de nœud il va falloir faire sur la page en incluant les descriptions des nœuds enfants. Nous appelons cette description de nœud un « nœud virtuel », usuellement abrégé en VNode (pour « virtual node »). « DOM virtuel » est le nom de l’arbre des VNodes construits par un arbre de composants Vue.
Arguments de createElement
La seconde chose à laquelle vous allez devoir vous familiariser est la manière d’utiliser les fonctionnalités des templates avec la fonction createElement
. Voici les arguments que la fonction createElement
accepte :
|
Objet de données dans le détail
Une chose est à noter : de la même manière que v-bind:class
et v-bind:style
ont un traitement spécial dans les templates, ils ont leurs propres champs dans les objets de données VNode. Cet objet vous permet également d’insérer des attributs HTML normaux ainsi que des propriétés du DOM comme innerHTML
(cela remplace la directive v-html
) :
|
Exemple complet
Avec toutes ces informations, nous pouvons finir le composant que nous avons commencé :
|
Contraintes
Les VNodes doivent être uniques
Tous les VNodes dans l’arbre des composants doivent être uniques. Cela signifie que la fonction de rendu suivante est invalide :
|
Si vous souhaitez réellement dupliquer le même élément/composant plusieurs fois, vous pouvez le faire avec une fonction fabrique. Par exemple, la fonction de rendu suivante est parfaitement valide pour faire le rendu de 20 paragraphes identiques :
|
Remplacer les fonctionnalités de template en pur JavaScript
v-if
et v-for
Partout où quelque chose peut être accompli simplement en JavaScript, les fonctions de rendu de Vue ne fournissent pas d’alternative propriétaire. Par exemple, un template utilisant v-if
et v-for
:
|
Cela pourrait être réécrit avec les if
/else
et map
du JavaScript dans une fonction de rendu
|
v-model
Il n’y a pas d’équivalent à v-model
dans les fonctions de rendu. Vous devez implémenter la logique vous-même :
|
C’est le prix à payer pour travailler au plus bas niveau, mais cela vous donne un meilleur contrôle sur le détail des interactions comparé à v-model
.
Modificateurs d’évènement et de code de touche
Pour les modificateurs d’évènement .passive
, .capture
et .once
, Vue offre des préfixes pouvant être utilisés dans on
:
Modificateur(s) | Préfixes |
---|---|
.passive |
& |
.capture |
! |
.once |
~ |
.capture.once ou.once.capture |
~! |
Par exemple :
|
Pour tous les autres modificateurs d’évènement et de code de touche, aucun préfixe propriétaire n’est nécessaire car il suffit d’utiliser des méthodes d’évènement dans le gestionnaire :
Modificateur(s) | Équivalence dans le gestionnaire |
---|---|
.stop |
event.stopPropagation() |
.prevent |
event.preventDefault() |
.self |
if (event.target !== event.currentTarget) return |
Touches :.enter , .13 |
if (event.keyCode !== 13) return (changez 13 en un autre code de touche pour les autres modificateurs de code de touche) |
Modificateurs de Clés :.ctrl , .alt , .shift , .meta |
if (!event.ctrlKey) return (changez respectivement ctrlKey par altKey , shiftKey , ou metaKey ) |
Voici un exemple avec tous ces modificateurs utilisés ensemble :
|
Slots
Vous pouvez accéder aux contenus des slots statiques en tant que tableaux de VNodes depuis this.$slots
:
|
Et accéder aux slots de portée en tant que fonctions qui retournent des VNodes via this.$scopedSlots
:
|
Pour passer des slots internes à un composant enfant en utilisant des fonctions de rendu, utilisez la propriété scopedSlots
dans les données du VNode :
|
JSX
Si vous écrivez beaucoup de fonctions render
, cela pourra vous sembler fatiguant d’écrire des choses comme ça :
|
Et d’autant plus quand la version template est vraiment simple en comparaison :
|
C’est pourquoi il y a un plugin Babel pour utiliser JSX avec Vue, nous permettant l’utilisation d’une syntaxe plus proche de celle des templates :
|
Utiliser h
comme alias de createElement
est une convention courante que vous verrez dans l’écosystème Vue et qui est en faite requise pour JSX. À partir de la version 3.4.0 du plugin Babel pour Vue, nous injections automatiquement const h = this.$createElement
dans n’importe quelle méthode ou accesseur (pas dans les fonctions ou fonctions fléchées), déclaré avec la syntaxe ES2015 qui a du JSX, vous pouvez ainsi oublier le paramètre (h)
. Avec les versions précédentes du plugin, si h
n’est pas disponible dans votre portée courante, votre application va lever une erreur.
Pour plus d’informations sur comment utiliser JSX dans du JavaScript, référez-vous à la documentation d’utilisation.
Composants fonctionnels
Le composant de titre ancré que nous avons créé plus tôt était relativement simple. Il ne gère aucun état, n’observe aucun état qu’on lui passe, et il n’a pas de méthodes de cycle de vie. Non, ce n’est qu’une simple fonction avec quelques props.
Dans des cas comme celui-ci, nous pouvons marquer les composants comme functional
, ce qui signifie qu’ils sont sans état (« stateless » c.-à-d. sans data
réactive) et sans instance (« instanceless » c.-à-d. sans contexte this
). Un composant fonctionnel ressemble à ça :
|
Note : dans les versions avant 2.3.0, l’option
props
est requise si vous souhaitez accepter des props dans un composant fonctionnel. Dans les versions 2.3.0+ vous pouvez omettre l’optionprops
et tous les attributs trouvés dans le nœud composant seront implicitement extraits comme des props.La référence sera HTMLElement quand elle sera utilisé avec des composants fonctionnels car elles sont sans état et sans instance.
Dans la 2.5.0+, si vous utilisez les composants monofichiers, les templates fonctionnels basés sur les composants peuvent être déclarés avec :
|
Tout ce dont le composant a besoin est passé dans l’objet context
, qui est un objet contenant :
props
: un objet avec les props fournies,children
: un tableau de VNode enfants,slots
: une fonction retournant un objet de slots,scopedSlots
: (2.6.0+) un objet qui expose les portées passées dans les slots. Expose également les slots normaux comme des fonctions,data
: l’objet de données (data
) complet passé au composant en tant que second argument decreateElement
,parent
: une référence au composant parent,listeners
: (2.3.0+) un objet contenant les écouteurs d’évènement enregistrés dans le parent. C’est un simple alias dedata.on
,injections
: (2.3.0+) si vous utilisez l’optioninject
, cela va contenir les injections résolues.
Après avoir ajouté functional: true
, mettre à jour la fonction de rendu de notre composant de titres avec ancres va simplement nécessiter d’ajouter l’argument context
, en remplaçant this.$slots.default
par context.children
, puis this.level
par context.props.level
.
Puisque les composants fonctionnels ne sont que des fonctions, leur rendu est plus rapide.
Ils sont également très utiles en tant que composants enveloppes. Par exemple, quand vous avez besoin de :
- Programmatiquement choisir un composant parmi plusieurs autres composants pour de la délégation ou
- Manipuler les enfants, props, ou données avant de les passer au composant enfant.
Voici un exemple d’un composant smart-list
qui délègue à des composants plus spécifiques en fonction des props qui lui sont passées :
|
Passer des attributs et évènements aux éléments / composants enfants
Sur les composants normaux, les attributs qui ne sont pas définis comme props sont automatiquement ajoutés à l’élément racine du composant en remplaçant ou en étant intelligemment rajouté sur n’importe quel attribut existant avec le même nom.
Cependant les composants fonctionnels vous demande de définir explicitement ce comportement :
|
En passant context.data
en tant que second paramètre à createElement
, nous transferrons à l’enfant racine n’importe quel attribut ou écouteur d’évènement utilisé sur my-functional-button
. C’est même tellement transparent que les évènements n’ont même pas besoin du modificateur .native
.
Si vous utilisez un composant fonctionnel basé sur un template, vous devrez aussi ajouter manuellement les attributs et les écouteurs. Puisque nous avons accès au contenus individuels du contexte, nous pouvons utiliser data.attrs
en le passant avec n’importes quel attribut HTML ou listeners
(l’alias pour data.on
) en le passant avec n’importe quel écouteur d’évènement.
|
slots()
vs. children
Vous vous demandez peut-être l’utilité d’avoir slot()
et children
en même temps. slots().default
n’est-il pas la même chose que children
? Dans la majorité des cas, oui. Mais que faire si vous avez un composant fonctionnel avec les enfants suivants ?
|
Pour ce composant, children
va vous donner les deux paragraphes, slots().default
ne vous donnera que le second, et slots().foo
ne vous donnera que le premier. Avoir le choix entre children
et slots()
vous permet donc de choisir ce que le composant sait à propos du système de slot ou si vous déléguez peut-être la responsabilité à un autre composant en passant simplement children
.
Compilation de template
Vous serez peut-être intéressé de savoir que les templates Vue sont en fait compilés en fonctions de rendu. C’est un détail d’implémentation dont vous n’avez en général pas à vous soucier, mais si vous souhaitez savoir comment un template spécifique est compilé, vous pourrez trouver cela intéressant. Vous trouverez ci-dessous une petite démo utilisant Vue.compile
pour voir en live le rendu d’une chaine de template :