Vue.js instruction System and custom instruction _javascript skills in daily learning

Source: Internet
Author: User
Tags event listener list of attributes modifiers

Basis

In addition to the built-in directives, Vue.js also allows you to register custom directives. Custom directives provide a mechanism for mapping data changes to DOM behavior.

A global custom directive can be registered with the vue.directive (ID, definition) method, which receives two parameter instruction IDs and defined objects. You can also register a local custom directive with the component's Directives option.

hook function

The definition object can provide several hook functions (all optional):

bind: Called only once, when the instruction is first bound to an element.

Update: Called immediately after bind with the initial value as the parameter, and then whenever the binding value changes, the parameter is the new value and the old value.

Unbind: Called only once, when the instruction is unbound from the element.

Example

Vue.directive (' my-directive ', {
 bind:function () {
  //Prepare to work
  //For example, add event handlers or just run a high cost task
 },
 update : function (NewValue, oldValue) {/
  /value Update work
  //will also be called once with the initial value of the parameter
 },
 unbind:function () {
  //cleanup work c13/>//For example, remove the event listener added by Bind ()}
)

After registering, you can use this in the Vue.js template (remember to add a prefix v):

<div v-my-directive= "somevalue" ></div>

When you need only the update function, you can pass in a function override definition object:

Vue.directive (' my-directive ', function (value) {
 //is used as update ()
})

Directive Instance Properties

All the hook functions will be copied into the actual instruction object, which in the hook points to the instruction object. This object exposes a number of useful properties:
el: An element of an instruction binding.
VM: The context ViewModel that owns the directive.
expression: An expression of an instruction, excluding parameters and filters.
ARG: The parameters of the instruction.
Name: The name of the directive, which does not contain a prefix.
Modifiers: An object that contains modifiers for the directive.
Descriptor: An object that contains the parsing result of the instruction.

You should treat these attributes as read-only and do not modify them. You can also add custom attributes to the instruction object, but be careful not to overwrite existing internal properties.

Example:

<div id= "Demo" v-demo:hello.a.b= "MSG" ></div>

Vue.directive (' demo ', {
 bind:function () {
  console.log (' demo bound! ')
 },
 update:function (value) {
  This.el.innerHTML =
   ' name-'    + this.name + ' <br> ' + '
   expression-' + This.expression + ' <br> ; ' +
   ' argument-'  + this.arg + ' <br> ' + '
   modifiers-' + json.stringify (this.modifiers) + ' <br> ' +
   ' value-'   + value
 }
} '
var demo = new Vue ({
 el: ' #demo ',
 data: {
  msg: ' Hello !'
 }
})

Object literal Amount

If the directive requires multiple values, you can pass in a JavaScript object literal. Remember that directives can use any valid JavaScript expression:

<div v-demo= "{color: ' White ', Text: ' Hello! '}" ></div>

Vue.directive (' demo ', function (value) {
 console.log (value.color)//"White"
 console.log (Value.text)//" Hello! "
})

Literal modifiers

When the instruction uses a literal modifier, its value is treated as a normal string and passed to the Update method. The Update method will only be invoked once, because normal strings cannot respond to data changes.

<div v-demo.literal= "foo bar baz" >

Vue.directive (' demo ', function (value) {
 Console.log (value)//"foo bar baz"
})

Element directives

Sometimes we want to use directives in the form of custom elements, rather than in the form of attributes. This is very similar to the angular "E" instruction. An element instruction can be viewed as a lightweight component. You can register a custom element directive as follows:

Vue.elementdirective (' my-directive ', {
 //API with normal instruction
 bind:function () {
  //Operation This.el ...}}
)

Do not write this:

<div v-my-directive></div>

Write this:

<my-directive></my-directive>

An element instruction cannot accept a parameter or an expression, but it can read the attributes of an element to determine its behavior.

Unlike ordinary directives, element directives are summative, which means that once Vue encounters an element instruction, it skips the element and its child elements-only the element directive itself can manipulate the element and its children.

Advanced options

Params

The custom directive can receive a params array, specifying a list of attributes that the Vue compiler will automatically extract from the binding element. For example:

<div v-example a= "HI" ></div>

Vue.directive (' example ', {
 params: [' a '],
 bind:function () {
  console.log (THIS.PARAMS.A)//-> "HI"
 }
})

This API also supports dynamic properties. This.params[key] will automatically stay updated. Alternatively, you can specify a callback that is invoked when the value changes:

<div v-example v-bind:a= "somevalue" ></div>

Vue.directive (' example ', {
 params: [' a '],
 paramwatchers: {
  a:function (val, oldval) {
   Console.log (' A changed! ')}}
)

Similar to props, the name of the instruction parameter uses the CamelCase style in JavaScript and corresponds to the kebab-case style in HTML. For example, suppose there is a parameter ' disable-effect ' in the template that accesses it in JavaScript in ' Disableeffect '.

Deep

If the custom directive is used on an object, and the update is triggered when the object's internal property changes, the deep:true is specified in the directive definition object.

<div v-my-directive= "obj" ></div>

Vue.directive (' my-directive ', {
 deep:true,
 update:function (obj) {
  //calling} When nested properties of ' obj ' are changed
)

TwoWay

If the directive wants to write back data to the Vue instance, specify Twoway:true in the directive definition object. This option allows This.set (value) to be used in directives:

Vue.directive (' example ', {
 twoway:true,
 bind:function () {
  This.handler = function () {
   //write data back to vm< c13/>//if the directive so binds v-example= "A.B.C"
   //It will set the ' VM.A.B.C '
   this.set (this.el.value)
  }.bind (this) with the given value
  this.el.addEventListener (' input ', This.handler)
 },
 unbind:function () {
  This.el.removeEventListener (' input ', This.handler)
 }}
)

Acceptstatement

Incoming acceptstatement:true allows custom directives to accept inline statements, just like v-on:

<div v-my-directive= "a++" ></div>

Vue.directive (' my-directive ', {
 acceptstatement:true,
 update:function (FN) {
  //incoming value is a function
  // The "a++" statement}} will be evaluated within the scope of the owning instance when it is invoked


Use wisely, because usually you have to avoid the side effects in the template.

Terminal

1.0.19+

Vue compiles modules by recursively traversing the DOM tree. But when it encounters the terminal instruction, it stops traversing the descendant elements of the element. This command takes over the task of compiling this element and its descendants. V-if and v-for are all terminal directives.

Writing a custom terminal directive is a high-level topic that requires a better understanding of the Vue compilation process, but this is not to say that it is not possible to write custom terminal directives. Using Terminal:true to specify custom terminal directives, you may also need to compile partial with vue.fragmentfactory. Here is a custom terminal directive that compiles its content template and injects the results into another part of the page:

var fragmentfactory = vue.fragmentfactory var
remove = Vue.util.remove
var createanchor = Vue.util.createAnchor

vue.directive (' inject ', {
 terminal:true,
 bind:function () {
  var container = document.getElementById (This.arg)
  This.anchor = Createanchor (' v-inject ')
  container.appendchild (this.anchor)
  Remove (this.el)
  var Factory = new Fragmentfactory (THIS.VM, this.el)
  This.frag = Factory.create (This._host, This._scope, This._frag) C12/>this.frag.before (This.anchor)
 },
 unbind:function () {
  this.frag.remove ()
  Remove ( This.anchor)
 }
)

<div id= "modal" ></div> ...
<div v-inject:modal>
  
 

If you want to write custom terminal directives, it is recommended that you read through the source code of the built-in terminal directives, such as V-if and v-for, in order to better understand the internal mechanism of Vue.

Priority

You can assign a priority to an instruction. If not specified, the normal instruction defaults to 1000, and the terminal directive defaults to 2000. Higher-priority directives on the same element are processed earlier than other instructions. Priority directives are processed sequentially in the order in which they appear in the list of element attributes, but they do not guarantee that the order is consistent in different browsers.

You can view the precedence of the built-in directives in the API. In addition, Process Control directives v-if and v-for always have the highest priority in the compilation process.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.