title | type | order |
---|---|---|
Directives personnalisées |
guide |
16 |
En supplément de la palette de directive fournie en standard (v-model
et v-show
), Vue vous permet également d'enregistrer vos propres directives. Notez qu'avec Vue 2, la forme de code préféré pour la réutilisabilité et l'abstraction est le composant. Il y a cependant des cas où vous aurez juste besoin d'un accès de bas niveau aux éléments du DOM, et c'est là que les directives personnalisées vous seraient utiles. Un exemple pourrait être la prise du focus sur un élément de champ, comme celui-ci :
{% raw %}
Quand la page charge, cet élément prend le focus (notez que l'autofocus ne fonctionne pas sur Safari mobile). En fait, si vous n'avez cliqué sur rien du tout depuis votre arrivée sur la page, le champ ci-dessous devrait avoir le focus. À présent, jetons un œil à la directive qui pourrait accomplir cela :
// Enregistrer une directive globale appelée focus
Vue.directive('focus', {
// Quand l'élément lié est inséré dans le DOM...
inserted: function (el) {
// L'élément prend le focus
el.focus()
}
})
Si vous préférez enregistrer à la place la directive en local, les composants acceptent également l'option directives
:
directives: {
focus: {
// définition de la directive
}
}
Puis dans un template, vous pouvez utiliser le nouvel attribut v-focus
sur n'importe quel élément, comme celui-ci :
<input v-focus>
Une définition d'objet directive peut fournir plusieurs fonctions de hook (toutes optionnelles) :
-
bind
: appelée une fois quand la directive est attachée à l'élément. C'est ici que vous pouvez effectuer les actions uniques d'initialisation. -
inserted
: appelée quand l'élément lié a été inséré dans son nœud parent (cela garanti uniquement sa présence dans le nœud parent, mais pas nécessairement dans le DOM principal). -
update
: appelée après que le composant conteneur ai été mis à jour, mais peut-être avant que ses enfants ai été mis à jour. La valeur de la directive peut ou pas avoir changé, mais vous pouvez ignorer les mises à jour inutiles en comparant les valeurs actuelles et anciennes de la liaison (voir plus bas les arguments de hook). -
componentUpdated
: appelée après que le composant conteneur et ses enfants ai été mis à jour. -
unbind
: appelée uniquement une fois, quand la directive est déliée de l'élément.
Nous allons explorer les arguments passés à ces hooks (c.-à-d. el
, binding
, vnode
, et oldVnode
) dans la prochaine section.
Les hooks d'une directive ont accès à ces arguments :
- el: L'élément sur lequel la directive est liée. Cela peut être utilisé pour directement manipuler le DOM.
- binding: Un objets contenant les propriétés suivantes.
- name: Le nom de la directive, sans le préfixe
v-
. - value: La valeur passée à la directive. Par exemple dans
v-my-directive="1 + 1"
, la valeur serait2
. - oldValue: La valeur précédente, seulement disponible dans
update
etcomponentUpdated
. Elle est disponible, que la valeur ai changé ou non. - expression: L'expression liée en tant que chaîne de caractère. Par exemple dans
v-my-directive="1 + 1"
, l'expression serait"1 + 1"
. - arg: L'argument passé à la directive, s'il y en a une. Par exemple dans
v-my-directive:foo
, l'argument serait"foo"
. - modifiers: Un objet contenant les modificateurs, s'il y en a. Par exemple dans
v-my-directive.foo.bar
, l'objet des modificateurs serait{ foo: true, bar: true }
.
- name: Le nom de la directive, sans le préfixe
- vnode: Le nœud virtuel produit par le compilateur Vue. Voir l'API VNode pour tous les détails.
- oldVnode: Le nœud virtuel précédent, seulement disponible dans les hooks
update
etcomponentUpdated
.
À l'exception de `el`, vous devez traiter ces arguments comme étant en lecture seule (« read-only ») et ne jamais les modifier. Si vous souhaitez partager des informations entre les hooks, il est recommandé de le faire à travers les attributs de données sur mesure de ses éléments (voir [dataset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset)).
Un exemple de directive personnalisée utilisant plusieurs de ces propriétés :
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#hook-arguments-example',
data: {
message: 'bonjour !'
}
})
{% raw %}
<script> Vue.directive('demo', { bind: function (el, binding, vnode) { var s = JSON.stringify el.innerHTML = 'name: ' + s(binding.name) + '' + 'value: ' + s(binding.value) + '
' + 'expression: ' + s(binding.expression) + '
' + 'argument: ' + s(binding.arg) + '
' + 'modifiers: ' + s(binding.modifiers) + '
' + 'vnode keys: ' + Object.keys(vnode).join(', ') } }) new Vue({ el: '#hook-arguments-example', data: { message: 'bonjour !' } }) </script> {% endraw %}
La plupart du temps, vous souhaiterez un même comportement pour les hooks bind
et update
, sans avoir besoin des autres hooks. Par exemple :
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
Si votre directive a besoin de plusieurs valeurs, vous pouvez également passer un objet JavaScript. Souvenez-vous, une directive peut accepter n'importe quelle expression JavaScript.
<div v-demo="{ color: 'white', text: 'bonjour !' }"></div>
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => "bonjour !"
})