Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Vue.js 2.0 custom instructions


May 07, 2021 Vue.js 2.0


Table of contents


Introduction to custom instructions

In addition to the default core instructions (v-model and v-show), Vue also allows custom instructions to be registered. N ote that in Vue 2.0, the main form and abstraction of code reusability is components -- however, in some cases, you still need to do the underlying work on pure DOM elements, and custom instructions are used at this point. The following example focuses on an input element, like this:

When the page loads, the element gets the focus. I n fact, input gets the focus without clicking on anything after you visit. Now let's refine this instruction:

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

You can also register local instructions, with the option to accept a directives in the component:

directives: {
  focus: {
    // 指令的定义---
  }
}

You can then use the new v-focus property on any element in the template:

<input v-focus>

Hook function

The instruction definition function provides several hook functions (optional):

  • bind: Called only once, the instruction is called the first time it is bound to an element, and this hook function allows you to define an initialization action that is performed once at binding time.
  • inserted: Called when the bound element is inserted into the parent node (the parent node exists to be called and does not have to exist in document).
  • update: Called when the template in which the bound element is located is updated, regardless of whether the binding value changes. Unnecessary template updates can be ignored by comparing binding values before and after updates (see latest for detailed hook function parameters).
  • componentUpdated: Called when the template in which the bound element is located completes an update cycle.
  • unbind: Called only once, when the instruction is untied from the element.

Let's take a look at the parameters of the hook function (including el, binding, vnode, old Vnode).

Hook function arguments

The hook function is given the following parameters:

  • el: The element bound by the instruction, which can be used to manipulate the DOM directly.
  • Binding: An object that contains the following properties:
    • name: Instruction name, excluding v-prefix.
    • value: The binding value of the instruction, for example: v-my-directive is "1 plus 1", and the value of value is 2.
    • oldValue: The previous value of the instruction binding is only available in the update and componentUpdated hooks. Available regardless of whether the value changes.
    • expression: The string form of the bound value. For example, v-my-directive is "1 plus 1" and the value of expression is "1 plus 1".
    • arg: The parameters passed to the instruction. For example, v-my-directive:foo, the value of arg is "foo".
    • modifiers: An object that contains modifiers. For example: v-my-directive.foo.bar, the modifier object modifiers has a value of sfoo:true, bar:true.
  • vnode: Vue compiles the generated virtual nodes and check out the VNode API for more details.
  • oldVnode: The previous virtual node is only available in update and componentUpdated hooks.

All parameters except el should be read-only and should not be modified as much as possible. If you need to share data between hooks, it is recommended that you do so through the dataset of the element.

A custom hook sample that uses these parameters:

<div id="hook-arguments-example" v-demo:hello.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!'
  }
})

Results:

name: "demo"
value: "hello!"
expression: "message"
argument: "hello"
modifiers: {"a":true,"b":true}
vnode keys: tag, data, children, text, elm, ns, context, functionalContext, key, componentOptions, child, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce

Short case of the function

Most of the time, we might want to repeat the action on the bind and update hooks, and we don't want to care about other hook functions. You can write this:

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

The literal amount of the object

If an instruction requires more than one value, you can pass in a JavaScript object literally. Remember, instruction functions can accept all legitimate types of Javascript expressions.

<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!"
})