I think you’ve all been exposed to v-ON, V-show and so on. What is a custom instruction? Custom directives are what you now think of as writing your own custom directives to manipulate DOM elements for code reuse purposes. When it comes to code reuse, I think we can all think of components, but it is important to note that the scope of custom directives and components is not the same. A component is usually one structure, one style, one logic that we reuse. Custom directives are used when we want to perform low-level operations on the DOM that have the same functionality.

Registration instructions are divided into global registration and local registration

Global registration:

Vue.directive('focus', {/ * * * /})
Copy the code

Local registration:

const vm = new Vue({
  el: '#app'.directives: {
    focus: {/ * * * /}}})Copy the code

Example: Write an auto-focus input box instruction V-focus

<body>
  <div id="app">
    <input type="text" v-focus>
  </div>

  <script>
    // Define a global directive
    Vue.directive("focus", {inserted(el){
         el.focus()
       }
    })
    // Define a local specification
     const vm = new Vue({
        el: "#app".data: {},
        directives: {
          focus: {
            inserted(el){ el.focus(); }},},</script>
</body>
Copy the code

Whenever there is an input box that needs automatic focus, add v-focus directly to it.

Note: When the global directive and the local directive name conflict, the local directive is used. Therefore, when you customize the directive, you can choose either global or local.

Results:

Custom instruction lifecycle hook functions

Next, we will elaborate on the custom instruction configuration object. The configuration object is not that difficult. It is a set of hook functions, which are executed at some point in time.

  • bind

The directive is executed when it is bound to a DOM element, and since it is bound only once, it is executed only once, where one-time initialization is possible.

  • 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 when the directive is unbound from a DOM element (the bound DOM element is removed by Vue) and only once.

Arguments to the hook function

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

  • Binding: Object containing the following properties:

    1. name: Indicates the command name, excluding the V – prefix
    2. value: The binding value of the instruction, for example: V-focus =”1+1″, the binding value is 2.
    3. oldValue: The preceding value of the directive binding, available only in the UPDATE and componentUpdated hooks.
    4. expression: Command expression in the form of a string. For example, v-focus=”1+1″, the expression is “1+1”
    5. arg: Optional parameter passed to the instruction. For example, in v-focus: SRC, the parameter is “SRC”
    6. modifiers: an object that contains modifiers. For example, in v-focus. Obj. Nice, the modifier object is {obj: true, nice: true}
  • Vnode: virtual node generated by Vue compilation.

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

Simulate the V-show command

<body>
    <div id="app">
      <input type="text" v-myshow="show" />
    </div>

    <script>
      // Simulate the show command
      Vue.directive("myshow", {
        bind(el, binding) {
          const { value } = binding;
          const display = value ? "" : "none";
          el.style.display = display;
        },
        update(el,binding) {
          const { value } = binding;
          const display = value ? "" :"none"; el.style.display = display; }});const vm = new Vue({
        el: "#app".data: {
          show: true,}});</script>
  </body>
Copy the code

Result demo:

If you trigger the same behavior in bind and update, regardless of the other hook functions, you can write it as a function like this:

<body>
    <div id="app">
      <input type="text" v-myshow="show" />
    </div>

    <script>
      // Simulate the show command
    
       Vue.directive("myshow".(el,binding) = >{
          const { value } = binding;
          const display = value ? "" : "none";
          el.style.display = display;
      });


      const vm = new Vue({
        el: "#app".data: {
          show: true,}});</script>
  </body>
Copy the code

Simulate the V-Modle instruction

 <body>
    <div id="app">
      <input type="text" v-mymodel="content" />{{ content }}
    </div>

    <script>
      // Simulate the V-model instruction
      Vue.directive("mymodel", {bind(el,binding,vnode){
          const vm= vnode.context;
          const {value,expression} = binding;
          el.value = binding.value
          el.oninput = function(){
            constinputValue = el.value; vm[expression] = inputValue; }},update(el,binding){
          const {value} = binding;
          el.value = value
        }
      })

      const vm = new Vue({
        el: "#app".data: {
          content:"Forensic"}});</script>
  </body>
Copy the code

Result demo: