Benutzerdefinierte Anweisungen


Inhaltsverzeichnis


Einführung


Zusätzlich zu den standardmäßig integrierten Befehlen für Kernfunktionen (v-model und v-show) ermöglicht Vue auch die Registrierung benutzerdefinierter Anweisungen. Beachten Sie, dass in Vue2.0 Komponenten die Hauptform der Wiederverwendung und Abstraktion von Code sind. In einigen Fällen müssen Sie jedoch dennoch Operationen auf niedriger Ebene für gewöhnliche DOM-Elemente ausführen. In diesem Fall werden benutzerdefinierte Anweisungen verwendet. Nehmen Sie ein Beispiel für ein fokussiertes Eingabefeld wie folgt:

4.gif

Wenn die Seite geladen wird, erhält das Element den Fokus (Hinweis: autofocus ist nicht verfügbar auf mobile Safari-Arbeit). Solange Sie nach dem Öffnen dieser Seite nichts angeklickt haben, sollte das Eingabefeld tatsächlich noch fokussiert sein. Nun verwenden wir eine Direktive, um diese Funktion zu implementieren:

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

Wenn Sie eine lokale Direktive registrieren möchten, akzeptiert die Komponente auch eine directives Option:

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

Dann können Sie sie zu jeder hinzufügen Element in der Vorlage Verwenden Sie das neue v-focus Attribute wie folgt:

<input v-focus>


Hook-Funktion


Ein Direktivendefinitionsobjekt kann sein wie folgt bereitgestellt Mehrere Hook-Funktionen (Beide sind optional):

  • bind: Wird nur einmal aufgerufen, wenn die Direktive zum ersten Mal an ein Element gebunden wird. Hier können einmalige Initialisierungseinstellungen vorgenommen werden.

  • inserted: Wird aufgerufen, wenn das gebundene Element in den übergeordneten Knoten eingefügt wird (nur der übergeordnete Knoten ist garantiert vorhanden, wird aber nicht unbedingt in das Dokument eingefügt).

  • update: Wird aufgerufen, wenn der VNode der Komponente aktualisiert wird, kann aber auftreten, bevor der untergeordnete VNode aktualisiert wird . Der Wert der Richtlinie kann sich geändert haben oder auch nicht. Sie können jedoch unnötige Vorlagenaktualisierungen ignorieren, indem Sie die Werte vor und nach der Aktualisierung vergleichen (siehe unten für detaillierte Parameter der Hook-Funktion).

Weitere Details zu VNodes werden wir später vorstellen, wenn wir die Rendering-Funktion besprechen.

  • componentUpdated: Wird aufgerufen, nachdem alle VNode und sein Sub-VNode der Komponente, in der sich die Anweisung befindet, aktualisiert wurden.

  • unbind: Wird nur einmal aufgerufen, wenn die Anweisung vom Element gelöst wird.

Als nächstes werfen wir einen Blick auf die Parameter der Hook-Funktion (also el, binding, vnode und oldVnode).


Hook-Funktionsparameter


Befehls-Hook Die Unterfunktion wird in den folgenden Parametern übergeben:

  • el: Das durch die Anweisung gebundene Element kann zur direkten Bedienung verwendet werden DOM.

  • binding: Ein Objekt mit den folgenden Eigenschaften:

    • name: Anweisungsname, ohne das v- Präfix.

    • value: Der verbindliche Wert der Anweisung, zum Beispiel: In v-my-directive="1 1" ist der verbindliche Wert 2.

    • oldValue: Der vorherige Wert der Anweisungsbindung, nur in den Hooks update und componentUpdated verfügbar. Verfügbar unabhängig davon, ob sich der Wert geändert hat.

    • expression: Anweisungsausdruck in Stringform. In v-my-directive="1 1" lautet der Ausdruck beispielsweise "1 1".

    • arg: An den Befehl übergebene Parameter, optional. In v-my-directive:foo lautet der Parameter beispielsweise "foo".

    • modifiers: Ein Objekt, das Modifikatoren enthält. Beispiel: In v-my-directive.foo.bar ist das Modifikatorobjekt { foo: true, bar: true }.

  • vnode: Virtueller Knoten, der durch Vue-Kompilierung generiert wird. Gehen Sie zu VNode API, um weitere Details zu erfahren.

  • oldVnode: Vorheriger virtueller Knoten, nur in den Hooks update und componentUpdated verfügbar.

Außer el sollten alle anderen Parameter schreibgeschützt sein und dürfen nicht geändert werden. Wenn Sie Daten zwischen Hooks teilen müssen, wird empfohlen, dies über dataset des Elements zu tun.

Hier ist ein Beispiel für einen benutzerdefinierten Hook, der diese Eigenschaften verwendet:

<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: 'hello!'
  }
})

1.jpg


Dynamische Befehlsparameter

Die Parameter der Direktive können dynamisch sein. Beispielsweise kann in v-mydirective:[argument]="value" der Parameter argument basierend auf Komponenteninstanzdaten aktualisiert werden! Dadurch können benutzerdefinierte Anweisungen flexibel in Anwendungen verwendet werden.

Sie möchten beispielsweise eine benutzerdefinierte Direktive erstellen, die Elemente mithilfe eines festen Layouts an die Seite anheftet. Wir können eine benutzerdefinierte Anweisung erstellen, die den Pixelwert der vertikalen Position durch den Anweisungswert wie folgt aktualisiert:

<div id="baseexample">
  <p>Scroll down the page</p>
  <p v-pin="200">Stick me 200px from the top of the page</p>
</div>
Vue.directive('pin', {
  bind: function (el, binding, vnode) {
    el.style.position = 'fixed'
    el.style.top = binding.value + 'px'
  }
})
new Vue({
  el: '#baseexample'
})

Dadurch wird das Element an einer Position von 200 Pixeln vom oberen Rand der Seite fixiert. Was aber, wenn das Szenario so aussieht, dass wir das Element links statt oben befestigen müssen? Zu diesem Zeitpunkt kann die Verwendung dynamischer Parameter sehr praktisch sein, um sie entsprechend jeder Komponenteninstanz zu aktualisieren.

<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>
rrree

Ergebnis:

1.gif

Auf diese Weise ist diese benutzerdefinierte Direktive jetzt flexibel genug, um einige verschiedene Anwendungsfälle zu unterstützen.


Funktionsabkürzung


Oft möchten Sie vielleicht bind und verwenden update löst das gleiche Verhalten aus, ohne sich um andere Hooks zu kümmern. Schreiben Sie zum Beispiel so:

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'
    }
  }
})


Objektliteral


Wenn die Anweisung es erfordert Bei mehreren Werten können Sie ein JavaScript-Objektliteral übergeben. Denken Sie daran, dass Direktivenfunktionen alle zulässigen JavaScript-Ausdrücke akzeptieren.

Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})
rrree