Base
Allowing you to register custom directives is essentially a new trick for Vue: how to map changes in data to the behavior of the DOM. You can use the (id, definition) method to pass in the directive id and define objects to register a global custom directive. Defining an object requires providing some hook functions (all optional):
- bind: Called only once, when the instruction binds the element for the first time.
- update:The first time is called immediately after bind, and the parameters obtained are the initial value of the binding; after that, whenever the bound value changes, it will be called, and two parameters of the new value and the old value are obtained.
-
unbind:Called only once, when the instruction unbinds the element.
example:
('my-directive', { bind: function () { // Prepare for binding // For example, add event listeners, or other complicated operations that only require one time }, update: function (newValue, oldValue) { // Perform the corresponding update based on the obtained new value // The initial value will also be called once }, unbind: function () { // Do cleaning // For example, remove the event listener added in bind() } })
Once you have registered a custom directive, you can use it in the template like this (the directive prefix that needs to be added, default is v-):
<div v-my-directive="someValue"></div>
If you only need the update function, you can pass in only one function without passing the definition object:
('my-directive', function (value) { // This function will be used as update() function})
All hook functions will be copied into the actual instruction object, and this instruction object will be this of all hook functions.
Context environment. Some useful public properties are exposed on the directive object:
el:Directive binding elements
vm: The context of this directive ViewModel
expression:Directive expressions, excluding parameters and filters
arg: Parameters of the instruction
raw: Unparsed original expression
name:Directive name without prefix
These properties are read-only, do not modify them. You can also attach custom properties to the directive object, but be careful not to overwrite existing internal properties.
Example of using directive object properties:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="/ajax/libs/vue/0.12.16/"></script> </head> <body> <div v-demo-directive="LightSlateGray : msg"></div> <script> ('demoDirective', { bind: function () { = '#fff' = }, update: function (value) { = 'name - ' + + '<br>' + 'raw - ' + + '<br>' + 'expression - ' + + '<br>' + 'argument - ' + + '<br>' + 'value - ' + value } }); var demo = new Vue({ el: '#demo', data: { msg: 'hello!' } }) </script> </body> </html>
Multiple clauses
Within the same feature, multiple comma-separated clauses will be bound to multiple instruction instances. In the following example, the directive will be created and called twice:
<div v-demo="color: 'white', text: 'hello!'"></div>
If you want to process multiple parameters with a single instruction instance, you can use a literal object as an expression:
<div v-demo="{color: 'white', text: 'hello!'}"></div>
('demo', function (value) { (value) // Object {color: 'white', text: 'hello!'} })
Literal commands
If isLiteral: true is passed in when creating a custom directive, then the attribute value will be regarded as a direct string and assigned to the expression of the directive. Literal instructions do not attempt to establish data monitoring.
example:
<div v-literal-dir="foo"></div>
('literal-dir', { isLiteral: true, bind: function () { () // 'foo' } })
Dynamic literal commands
However, in cases where the literal directive contains the Mustache tag, the directive behaves as follows:
The instruction instance will have a property, this._isDynamicLiteral is set to true;
If the update function is not provided, the Mustache expression is evaluated only once and assigns the value to. Expressions are not monitored for data.
If the update function is provided, the instruction will establish a data monitoring for the expression and call update when the calculation result changes.
Two-way command
If your directive wants to write back data to the Vue instance, you need to pass in twoWay: true . This option allows (value) to be used in directives.
('example', { twoWay: true, bind: function () { = function () { // Write data back to vm // If the command binds v-example="" like this, // Here will be assigned a value to `` () }.bind(this) ('input', ) }, unbind: function () { ('input', ) } })
Inline statements
Passing in acceptStatement: true allows custom directives to accept inline statements like v-on:
<div v-my-directive="a++"></div>
('my-directive', { acceptStatement: true, update: function (fn) { // the passed in value is a function which when called, // will execute the "a++" statement in the owner vm's // scope. } })
But please use this feature wisely, as we usually want to avoid side effects in the template.
In-depth data observation
If you want to use custom directives on an object and can also trigger the update function of the directive when the nested properties inside the object change, then you have to pass deep: true into the directive definition.
<div v-my-directive="obj"></div>
('my-directive', { deep: true, update: function (obj) { // This function will also be called when the properties nested inside obj change } })
Instruction priority
You can choose to provide a priority number for the instruction (default is 0). The higher the priority of the same element, the earlier the instructions will be handled than the other instructions. Directives with the same priority will be processed in the order in which they appear in the element property list, but it cannot be guaranteed that this order is consistent in different browsers.
Generally speaking, as a user, you don’t need to care about the priority of built-in instructions. If you are interested, you can refer to the source code. Logical control instructions v-repeat, v-if are considered "terminal instructions" and they always have the highest priority during compilation.
Elemental Directive
Sometimes, we may want our directives to be used as custom elements instead of as a feature. This is very similar to the concept of Angular's Class E directive. Element directives can be regarded as a lightweight custom component (which will be discussed later). You can register a custom element directive like this:
('my-directive', { // Consistent with the API of ordinary directives bind: function () { // Perform operation... } })
When using it, we no longer use this writing method:
<div v-my-directive></div>
Instead, it is written as:
<my-directive></my-directive>
An element instruction cannot accept parameters or expressions, but it can read the characteristics of an element to determine its behavior. A big difference from the usual directives, an element directive is final, which means that once Vue encounters an element directive, it will skip compilation of that element and its child elements - i.e. only the element directive itself can operate on the element and its child elements.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.