Instructions personnalisées


Table des matières


Introduction


En plus des fonctions de base, les instructions intégrées par défaut (v-model et v-show< /code>), Vue permet également d'enregistrer des directives personnalisées. Notez que dans Vue2.0, la principale forme de réutilisation et d'abstraction de code concerne les composants. Cependant, dans certains cas, vous devez toujours effectuer des opérations de bas niveau sur des éléments DOM ordinaires, auquel cas des directives personnalisées sont utilisées. Prenons un exemple de concentration sur la zone de saisie comme suit : v-modelv-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子,如下:

4.gif

当页面加载时,该元素将获得焦点 (注意:autofocus 在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。现在让我们用指令来实现这个功能:

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

如果想注册局部指令,组件中也接受一个 directives 的选项:

directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:

<input v-focus>


钩子函数


一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update4.gif

  • Lors du chargement de la page, l'élément aura le focus (remarque : autofocus ne fonctionne pas sur Safari mobile). En fait, tant que vous n'avez cliqué sur rien après avoir ouvert cette page, la zone de saisie doit toujours être ciblée. Utilisons maintenant les directives pour réaliser cette fonctionnalité :
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Si vous souhaitez enregistrer des directives locales, le composant accepte également une option directives :

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: 'hello!'
  }
})
Ensuite, vous pouvez utiliser la nouvelle sur n'importe quel élément du attribut v-focus du modèle, comme suit :
<div id="baseexample">
  <p>Scroll down the page</p>
  <p v-pin="200">Stick me 200px from the top of the page</p>
</div>

🎜🎜Fonction Hook🎜🎜🎜🎜🎜Un objet de définition de commande peut fournir les fonctions de hook suivantes ( Tous sont facultatifs) : 🎜🎜🎜🎜🎜bind : Appelé une seule fois, lorsque l'instruction est liée à l'élément pour la première fois. Les paramètres d'initialisation uniques peuvent être effectués ici. 🎜🎜🎜🎜insert : Appelé lorsque l'élément lié est inséré dans le nœud parent (seul le nœud parent est garanti d'exister, mais pas nécessairement inséré dans le document). 🎜🎜🎜🎜update : Appelé lorsque le VNode du composant est mis à jour, 🎜mais cela peut se produire avant que son VNode enfant ne soit mis à jour🎜. La valeur de la directive peut avoir changé ou non. Mais vous pouvez ignorer les mises à jour inutiles du modèle en comparant les valeurs avant et après la mise à jour (voir ci-dessous pour les paramètres détaillés de la fonction hook). 🎜🎜🎜🎜🎜Nous présenterons plus de détails sur les VNodes 🎜plus tard🎜 lorsque nous discuterons des 🎜fonctions de rendu🎜. 🎜

  • componentUpdated : Appelé après que tous les VNode componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 elbindingvnode 和 oldVnode)。


钩子函数参数


指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM 。

  • binding:一个对象,包含以下属性:

    • name:指令名,不包括 v- 前缀。

    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2

    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。

    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"

    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"

    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }

  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset et ses sous-VNode du composant où se trouve l'instruction ont été mis à jour.

unbind : Appelé une seule fois, lorsque l'instruction n'est pas liée à l'élément.

Jetons ensuite un œil aux paramètres de la fonction hook (c'est-à-dire el, binding, vnode et oldVnode). 1.jpg


Paramètres de la fonction Hook


La fonction hook de commande sera transmise comme suit Paramètres :

el : L'élément lié à l'instruction peut être utilisé pour faire fonctionner directement le DOM. 🎜🎜🎜binding : Un objet contenant les propriétés suivantes : 🎜
    🎜🎜name : Nom de l'instruction, à l'exclusion du préfixe v-. 🎜🎜🎜value : La valeur de liaison de l'instruction, par exemple : dans v-my-directive="1 + 1", la valeur de liaison est 2. 🎜🎜🎜oldValue : La valeur précédente de la liaison d'instruction, disponible uniquement dans les hooks update et componentUpdated. Disponible même si la valeur a changé. 🎜🎜🎜expression : Expression d'instruction sous forme de chaîne. Par exemple, dans v-my-directive="1 + 1", l'expression est "1 + 1". 🎜🎜🎜arg : Paramètres passés à la commande, facultatifs. Par exemple, dans v-my-directive:foo, le paramètre est "foo". 🎜🎜🎜modifiers : Un objet contenant des modificateurs. Par exemple : Dans v-my-directive.foo.bar, l'objet modificateur est { foo : true, bar : true . 🎜
🎜🎜vnode : Le nœud virtuel généré par la compilation Vue. Accédez à l'API VNode🎜 pour en savoir plus. . 🎜🎜🎜oldVnode : Le nœud virtuel précédent, disponible uniquement dans les hooks update et componentUpdated. 🎜
🎜À l'exception de el, tous les autres paramètres doivent être en lecture seule et ne doivent pas être modifiés. Si vous devez partager des données entre hooks, il est recommandé de transmettre le dataset🎜 pour continuer. 🎜🎜🎜Voici un exemple de hook personnalisé qui utilise ces propriétés : 🎜
Vue.directive('pin', {
  bind: function (el, binding, vnode) {
    el.style.position = 'fixed'
    el.style.top = binding.value + 'px'
  }
})
new Vue({
  el: '#baseexample'
})
<div id="dynamicexample">
  <h3>Scroll down inside this section ↓</h3>
  <p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>
</div>
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜Paramètres de directive dynamique🎜🎜🎜

Les paramètres de la directive peuvent être dynamiques. Par exemple, dans v-mydirective:[argument]="value", le paramètre argument peut être mis à jour en fonction des données d'instance du composant ! Cela permet aux directives personnalisées d'être utilisées de manière flexible dans les applications. v-mydirective:[argument]="value" 中,argument 参数可以根据组件实例数据进行更新!这使得自定义指令可以在应用中被灵活使用。

例如你想要创建一个自定义指令,用来通过固定布局将元素固定在页面上。我们可以像这样创建一个通过指令值来更新竖直位置像素值的自定义指令:

Vue.directive('pin', {
  bind: function (el, binding, vnode) {
    el.style.position = 'fixed'
    var s = (binding.arg == 'left' ? 'left' : 'top')
    el.style[s] = binding.value + 'px'
  }
})
new Vue({
  el: '#dynamicexample',
  data: function () {
    return {
      direction: 'left'
    }
  }
})
Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})

这会把该元素固定在距离页面顶部 200 像素的位置。但如果场景是我们需要把元素固定在左侧而不是顶部又该怎么办呢?这时使用动态参数就可以非常方便地根据每个组件实例来进行更新。

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Vue.directive('demo', function (el, binding) {
  console.log(binding.value.color) // => "white"
  console.log(binding.value.text)  // => "hello!"
})

结果:

1.gif

这样这个自定义指令现在的灵活性就足以支持一些不同的用例了。


函数简写


在很多时候,你可能想在 bindupdate

Par exemple, vous souhaitez créer une directive personnalisée pour corriger des éléments sur la page via une mise en page fixe. Nous pouvons créer une directive personnalisée qui met à jour la valeur du pixel de position verticale par la valeur de la directive comme ceci :

rrreeerrreee
Cela fixera l'élément à une position de 200 pixels à partir du haut de la page. Mais que se passe-t-il si le scénario est que nous devons fixer l'élément à gauche plutôt qu'en haut ? À l'heure actuelle, les paramètres dynamiques peuvent être utilisés pour mettre à jour très facilement chaque instance de composant.

rrreeerrreee

Résultats : 1.gifDe cette façon, cette directive personnalisée est désormais suffisamment flexible pour prendre en charge quelques cas d'utilisation différents.



Abréviation de fonction

🎜Dans de nombreux cas, vous souhaiterez peut-être déclencher lorsque bind et update Même comportement quels que soient les autres hooks. Par exemple, écrivez comme ceci :🎜rrreee🎜🎜🎜🎜🎜🎜Littéral d'objet🎜🎜🎜🎜🎜Si l'instruction nécessite plusieurs valeurs, vous pouvez transmettre un littéral d'objet JavaScript. N'oubliez pas que les fonctions de directive acceptent toutes les expressions JavaScript légales. 🎜🎜rrreeerrreee🎜🎜🎜🎜 🎜