Vue custom instructions and usage

1, What are instructions

When learning vue, you will be exposed to instructions, so what is instruction?

  • vue provides some outputs that are more convenient for pages and data. These operations are called instructions and are represented by v-xxx, such as the attribute < div v-xxx / div > in html pages
  • For example, in angular, an instruction that starts with ng XXX is called an instruction
  • The instruction encapsulates some DOM behaviors and takes attributes as a code. The code has corresponding values. According to different values, relevant DOM operations will be bound, that is, some template operations can be performed

Some built-in v-xxx instructions commonly used in vue

  • v-text: the innerText attribute of an element can only be used in double labels. It has the same effect as {}} and is less used
  • v-html: innerHTML of an element, which is actually an assignment to innerHTML of an element
  • v-show: display and hide of elements, switching based on css style. If you are sure to hide, display: none will be added to the style of the element
  • v-if: insert and remove elements, which is equivalent to destroying and creating elements. If the value of the expression is false, a <---- As a tag, if the future value of v-if is true, insert the element here (if there is else, don't leave a pit alone).
  • V-else-if: the previous adjacent element must have v-if or v-else-if
  • V-else: the previous adjacent element must have v-if or v-else-if. If both v-if and v-else-if have corresponding expressions, v-else can write directly
  • v-for: used to iterate through a set of data (arrays or objects). You must use a specific syntax: v-for = "alias in expression". Note: when v-for and v-if are in the same node, the priority of v-for is higher than that of v-if. That is, v-if will run in each v-for loop
  • v-on: mainly used to monitor dom time and then perform some operations. Abbreviated as [@]
  • v-model: used to create bidirectional data binding on form controls such as input/textarea.
  • v-bind: dynamically bind one or more attributes. It is often used to bind class, style, href, etc.
  • v-once: components and elements are rendered only once. When the data changes, they will not be re rendered.

2, Hook function of custom instruction

Vue provides five hook functions for custom instructions:

bind: The instruction is called the first time it is bound to an element and is executed only once. One time initialization settings can be performed here.
inserted: The bound element is inserted into the parent node DOM Called when in (only the parent node is guaranteed to exist).
update: Called when the component is updated.
componentUpdated: Called when components and subcomponents are updated.
unbind: Called when the instruction is unbound from the element and executed only once.

be careful:

	1,except update And componentUpdated In addition to hook functions, each hook function contains el,binding,vnode These three parameters
	2,In each function, the first argument is always el, Represents the one to which the instruction is bound dom Element, this el Parameter is a native JS object
	   therefore Vue Custom directives can be used to directly and DOM Deal with
	3,binding Is an object that contains the following properties: name,value,oldValue,expression,arg,modifiers
	4,oldVnode Only in update And componentUpdated Effective in hook
	5,except el outside, binding,vnode Properties are read-only

Hook function is life cycle, that is, when an instruction is bound to an element, there are five life cycle event functions inside the instruction. Next, create a case to see the triggering of these hook functions:

<p v-test>This is a text</p>
​
export default {
    ... ...
    directives: {
        test: {
              bind () {
                console.log('bind')
              },
              inserted () {
                console.log('inserted')
              },
              update () {
                console.log('update')
              },
              componentUpdated () {
                console.log('componentUpdated')
              },
              unbind () {
                console.log('unbind')
              }
        }
    }
}


Summary:

	bind(): When the instruction is bound to HTML Triggered on element
	inserted(): Triggered when an instruction bound element is inserted into the parent node
	update(): When the instruction is bound to the element state/Style and content(This refers to the binding of elements vue data) Triggered when a change occurs
	componentUpdated(): When update() Triggered after execution
	unbind(): When an instruction binds an element from dom Triggered when deleted from

Here are some chestnuts for application scenarios:
1. The input box automatically gets the focus (official example).
2. Click the area outside the drop-down menu to hide the menu.
3. Check the mailbox and phone number entered.

On the above occasions, other methods can be used to replace the project, but vue user-defined instructions can be defined in one place and called globally, making the code concise, efficient and easier to maintain.

The instruction registration method is the same as the "filter", "mixed in" and "component" registration methods. They are divided into two types: global registration and local registration.

3, Global instruction

// Add a random background to the element
<div v-bgcolor></div>
   
Vue.directive('bgcolor', {
    bind: function(el, binding, vnode) {
        el.style.backgroundColor = "#" + Math.random().toString(16).slice(2,8);
    }
})

Note: when defining, the name of the instruction does not need to be prefixed with v-prefix. When calling, the specified name must be prefixed with v-prefix for calling

4, Local instruction

// Same level as data and methods
methods: {},
directives: {
    bgcolor: {
         bind: function(el, binding) {
            el.style.backgroundColor = "#" + Math.random().toString(16).slice(2,8);
        }
    }
}

Personally, I prefer to use the global registration method, because since the user-defined instructions have been used, they should be general and reusable. Therefore, it is more valuable to provide the instructions used in the whole project, not only within a component. If you use it in a single place, just bring out the functions directly. Why bother.

5, Custom instruction with parameters

<div v-bgcolor='{color: 'orange'}'></div>

Vue.directive('bgcolor', {
    bind: function(el, binding) {
        el.style.backgroundColor = binding.value.color;
    }
})

6, Function abbreviation

If you want to trigger the same behavior during bind and update without caring about other hooks, you can write as follows:

// overall situation
Vue.directive('bgcolor', function (el, binding) {
      el.style.backgroundColor = binding.value
})

// local
directives: {
    bgcolor: (el, binding) => {
        el.style.backgroundColor = binding.value  
    }
}

7, Application examples

After we are familiar with the creation method and parameters of the instruction, we use it to create two actual cases.

1. The function of clicking on the blank submenu to hide is realized through the command, and the specific code is as follows:

// clickOutside.js
export default {
    bind (el, binding) {
        const self = {} // Define a private variable so that event listening can be cancelled in unbind
        self.documentHandler = (e) => {
            if (el.contains(e.target)) { // Here, it is determined whether the bound element contains the click element. If so, it returns
                return false
            }
            if (binding.value) { // Determine whether a value is bound in the instruction
                binding.value(e) // If a function is bound, call that function. binding.value here is the handleClose method
            }
            return true
        }
        document.addEventListener('click', self.documentHandler)
    },
    unbind (el) {
        // Disable event listening
        document.removeEventListener('click', self.documentHandler)
        delete self.documentHandler
    }
}

Use in components:

<template>
    <div>
        <div v-show="isShow" v-clickoutside="handleClickOutside" @click="showOrHide">
            Submenu ... 
        </div>
    </div>
</template>
​
<script>
    import clickoutside from './js/clickOutside'
    
    export default {
        ... ...
        directives: {
            clickoutside
        },
        data() {
            return {
                isShow: true,
            };
        },
        methods: {
            handleOutsideClick () {
                this.isShow = false
            }
        }
    }
</script>

2. Custom instructions to optimize the loading of pictures: during the loading process, the gray background is used to occupy the space when the picture is not loaded, and the picture is displayed directly after loading

<template>
    <div>
        <!-- Parameters cannot be filled in directly url address-->
        <img v-imgUrl='url' /> 
    </div>
</template>
​
<script>
    export default {
        data () {
            return {
                url: '../src/assets/logo.png'
            }
        }
    }
</script>

// Global registration
Vue.directive('imgUrl', function (el, binding) {
    el.style.backgroundColor = '#FeFe '/ / set background color
    var img = new Image()
    img.src = binding.value // Parameters after the binding.value instruction
    img.onload = function () {
        el.style.backgroundColor = ''
        el.src = binding.value
    }
})

Tags: Javascript Front-end Vue Vue.js

Posted on Thu, 11 Nov 2021 06:15:33 -0500 by MattReider