• This is the 8th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Last time, we briefly introduced what a custom instruction is. In this lesson, we will explain the application of the function in a custom instruction

Hook function

The custom directive object provides optional hook functions for use.

bind

Only called once, the first time a directive is bound to an element. This is where you can perform one-time initialization Settings.

inserted

Called when the bound element is inserted into the parent (the parent is guaranteed to exist, but not necessarily inserted into the document).

update

Called when the component’s VNode is updated, but may occur before its child VNodes are updated.

componentUpdated

Called after the VNode of the component where the directive resides and its child VNodes are all updated.

unbind

Called only once, when the directive is unbound from the element (the bound Dom element is removed by Vue).

Hook function arguments

  • El: The element bound by the directive that can be used to manipulate the DOM directly.

  • Binding: Object containing the following properties:

    • Name: indicates the command name, excluding the V – prefix.
    • Value: specifies the binding value of the directive. For example, v-my-directive=”1 + 1″, the binding value is 2.
    • OldValue: The previous value of the directive binding, available only in the UPDATE and componentUpdated hooks. Available regardless of whether the value changes.
    • Expression: command expression in the form of a string. For example, if v-my-directive=”1 + 1″, the expression is “1 + 1”.
    • Arg: Optional parameter passed to the instruction. For example, v-my-directive:foo, the parameter is “foo”.
    • Modifiers: An object that contains modifiers. For example, in v-my-directive.foo.bar, the modifier object is {foo: true, bar: true}.
  • Vnode: virtual node generated by Vue compilation.

  • OldVnode: Last virtual node, available only in update and componentUpdated hooks.

practice

Simulation of v – show

 // Bind to false, display to none, true, display to ""
Vue.directive('myshow', {
  bind (el, binding, vnode, oldVnode) {
    var display = binding.value ? ' ' : 'none';
    el.style.display = display;
  },
  update (el, binding, vnode, oldVnode) {
    var display = binding.value ? ' ' : 'none'; el.style.display = display; }})Copy the code

Simulation of v – model

 // 1. Set value to the element based on the bound data
 // 2. Change the value of the data when the input event is triggered
 // 3. Synchronize the input value after changing the data
Vue.directive('mymodel', {
  bind (el, binding, vnode) {
    const vm = vnode.context;
    const { value, expression } = binding;
    el.value = value;

    el.oninput = function (e) {
      const inputVal = el.value;
      vm[expression] = inputVal;
    }
  },
  update (el, binding) {
    const{ value } = binding; el.value = value; }})Copy the code

Write a V-slice

Vue.directive('slice', {
  bind (el, binding, vnode) {
    const vm = vnode.context;
    let { value, expression, arg, modifiers } = binding;

    if(modifiers.number) {
      value = value.replace(/[^0-9]/g.' ');
    }


    el.value = value.slice(0, arg);
    vm[expression] = value.slice(0, arg);

    el.oninput = function (e) {
      let inputVal = el.value;

      if(modifiers.number) {
        inputVal = inputVal.replace(/[^0-9]/g.' ');
      }

      el.value = inputVal.slice(0, arg);
      vm[expression] = inputVal.slice(0, arg);
    }
  },
  update (el, binding, vnode) {
    const vm = vnode.context;
    let { value, arg, expression, modifiers } = binding;

    if(modifiers.number) {
      value = value.replace(/[^0-9]/g.' ');
    }

    el.value = value.slice(0, arg);
    vm[expression] = value.slice(0, arg); }})Copy the code

Dynamic instruction parameter

The parameters of an instruction can be dynamic. For example, v-directive:[arguments]=”value, the argument argument can be updated based on component instance data.

Rewrite the v – slice

Vue.directive('slice', {
  bind (el, binding, vnode) {
    const vm = vnode.context;
    let { value, expression, arg, modifiers } = binding;

    if(modifiers.number) {
      value = value.replace(/[^0-9]/g.' ');
    }


    el.value = value.slice(0, arg);
    vm[expression] = value.slice(0, arg);

    el.oninput = function (e) {
      let inputVal = el.value;

      if(modifiers.number) {
        inputVal = inputVal.replace(/[^0-9]/g.' ');
      }

      el.value = inputVal.slice(0, arg);
      vm[expression] = inputVal.slice(0, arg);
    }
  },
  update (el, binding, vnode) {
    const vm = vnode.context;
    let { value, arg, expression, modifiers } = binding;
    
    if(modifiers.number) {
      value = value.replace(/[^0-9]/g.' ');
    }

    el.value = value.slice(0, arg);
    vm[expression] = value.slice(0, arg);

    el.oninput = function (e) {
      let inputVal = el.value;

      if(modifiers.number) {
        inputVal = inputVal.replace(/[^0-9]/g.' ');
      }

      el.value = inputVal.slice(0, arg);
      vm[expression] = inputVal.slice(0, arg); }}})Copy the code

Function shorthand

When you want to trigger the same behavior in bind and update, regardless of the other hooks, you can write it as a function:

Vue.directive('myshow'.(el, binding) = > {
  const { value } = binding;
  const display = value ? ' ' : 'none';
  el.style.display = display;
})
Copy the code
Vue.directive('slice'.(el, binding, vnode) = > {
  const vm = vnode.context;
  let { value, expression, arg, modifiers } = binding;

  if(modifiers.number) {
    value = value.replace(/[^0-9]/g.' ');
  }


  el.value = value.slice(0, arg);
  vm[expression] = value.slice(0, arg);

  el.oninput = function (e) {
    let inputVal = el.value;

    if(modifiers.number) {
      inputVal = inputVal.replace(/[^0-9]/g.' ');
    }

    el.value = inputVal.slice(0, arg);
    vm[expression] = inputVal.slice(0, arg); }})Copy the code

Object literals

If a custom directive requires multiple values, you can pass in a JS object literal. The instruction function can accept all valid JS expressions.

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Copy the code
Vue.directive('demo'.function (el, binding) {
  console.log(binding.value.color)  // => "white" 
  console.log(binding.value.text)   // => "hello!" 
})
Copy the code

The last

If it is helpful to you, I hope to give you a 👍 comment/collection/three even!

Bloggers are honest and answer questions for free ❤