Vue.js Learning item13– instruction system and custom directives

Source: Internet
Author: User
Tags list of attributes modifiers

Basis

In addition to the built-in directives, Vue.js also allows the registration of custom directives. A custom directive provides a mechanism to map changes in data to DOM behavior.

You can Vue.directive(id, definition) register a global custom directive with a method that receives two parameter instruction IDs and definition objects . You can also directives register a local custom directive with the component's options.

hook function

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

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

    • Update: bind immediately after the first call with the initial value for 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 () {    // 准备工作 // 例如,添加事件处理器或只需要运行一次的高耗任务 }, update: function (newValue, oldValue) { // 值更新时的工作 // 也会以初始值为参数调用一次 }, unbind: function () { // 清理工作 // 例如,删除 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 update a function, you can pass in a function substitution definition object:

Vue.directive(‘my-directive‘, function (value) {  // 这个函数用作 update()})
Instruction Instance Properties

All the hook functions are copied to the actual instruction object , and the hooks this point to the instruction object. This object exposes a number of useful properties:

    • El: The element that the directive binds to.
    • VM: The context ViewModel that owns the directive.
    • expression: Expressions for directives, excluding parameters and filters.
    • arg: The parameter of the directive.
    • Name: The directive is named, and does not contain a prefix.
    • modifiers: An object that contains the modifier of the directive.
    • Descriptor: An object that contains the parsing result of the instruction.

You should treat these properties as read-only and do not modify them. You can also add custom attributes to a directive 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.ex pression + ' <br> ' + ' argument-' + This.arg + ' <br> ' + ' modifiers-' + Json.strin Gify (this.modifiers) + ' <br> ' + ' value-' + value} 'var demo = New Vue ({el: ' #demo ') , data: {msg: ' hello! '}})               
Object literal

If the instruction requires more than one value, you can pass in a JavaScript object literal. Remember that directives can use any of the legitimate JavaScript expressions:

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

When the instruction uses a literal modifier, its value is treated as a normal string and passed to the update method. updatemethod will be called only 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 directive

Sometimes we want to use directives in the form of custom elements, rather than in the form of attributes. This is very similar to Angular's "E" directive. An element directive can be seen as a lightweight component. You can register a custom element directive like this:

Vue.elementDirective(‘my-directive‘, {  // API 同普通指令  bind: function () { // 操作 this.el... }})

Don't write like this:

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

Write this:

<my-directive></my-directive>

An element directive cannot accept arguments or expressions, but it can read the attributes of an element to determine its behavior.

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

Advanced options Params

Custom directives can receive an params array, specify a list of attributes, and the Vue compiler will automatically extract these attributes of 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]is automatically kept up to date. Alternatively, you can specify a callback to invoke 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 directive parameter is used in JavaScript CamelCase style, corresponding to the use of kebab-case style in HTML. For example, suppose there is a parameter ' disable-effect ' in the template that accesses it in JavaScript with ' Disableeffect '.

Deep

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

<div v-my-directive="obj"></div>
Vue.directive(‘my-directive‘, {  deep: true,  update: function (obj) { // 在 `obj` 的嵌套属性变化时调用 }})
TwoWay

If the directive wants to write back data to the Vue instance, it is specified in the directive definition object twoWay: true . This option allows for use in directives this.set(value) :

Vue.directive (' Example ', {twoWay:True, bind:function  () {this.handler = function  () { //writes data back to VM //if the directive binds v-example= "A.B.C" //It will be set with the given value ' VM.A.B.C ' this.set (this.el.value )}.bind (this) this.el.addeventlistener ( this.handler)}, Unbind: function  () {this.el.removeeventlistener (              
Acceptstatement

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

<div v-my-directive="a++"></div>
Vue.directive(‘my-directive‘, {  acceptStatement: true,  update: function (fn) { // 传入值是一个函数 // 在调用它时将在所属实例作用域内计算 "a++" 语句 }})

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

Terminal

1.0.19+

Vue compiles the module by recursively traversing the DOM tree. But when it encounters the terminal instruction, it stops traversing the descendant elements of the element. This command will take over the task of compiling the element and its descendants. v-ifand v-for both are terminal instructions.

Writing a custom terminal directive is a high-level topic that requires a good understanding of the Vue compilation process, but this is not to say that it is not possible to write custom terminal directives. You terminal: true may also need to compile partial with the specified custom terminal Directive Vue.FragmentFactory . Here is a custom terminal directive that compiles its content template and injects the results to another place on the page:

var fragmentfactory = Vue.fragmentfactoryvar remove = Vue.util.removevar createanchor = Vue.util.createAnchorVue.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)  This.frag.before (this.anchor)}, Unbind: function  () {this.frag.remove () Remove (this.anchor)})           
< div id= "modal" > </DIV> <div v-inject:modal> <h1>header</ h1> <p>body </p> < P>footer</p></DIV>              

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

Priority

You can assign a priority to the directive. If not specified, the normal instruction is by default 1000 , the terminal directive is the default 2000 . Commands with higher precedence on the same element will be processed earlier than other directives. Commands with the same precedence are processed sequentially in the order in which they appear in the list of element attributes, but there is no guarantee that the order will be consistent across browsers.

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

Vue.js Learning item13– instruction system and custom directives

Related Article

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.