This is my third article about getting started

This is the last assignment for beginners, the last assignment, but not the last blog post. Thank you very much recommendation officer, help me to the first two are recommended to the home page, hey hey.

What is a custom directive

Because vue has common built-in directives (V-model, V-bind, V-ON, etc.), you’ll have multiple places to use the same functionality for project requirements, such as: The project needs to input the number of days in a month, we know 1-31, so we need to limit the maximum and minimum and not have a decimal point. Of course, some requirements need to keep several digits after the decimal point, such as the amount and so on (no, you know!). . You can also do this using methods, but using custom directives makes your code look more concise and understandable.

The body of the

vue2.x

Let’s take a look at the custom specified life cycle:

  • bind: called only 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 node.
  • update: is called when the component’s VNode is updated, but may occur before its child VNodes are updated. The value of the instruction may or may not have changed. But you can ignore unnecessary template updates by comparing the values before and after the update.
  • componentUpdated: invoked after the VNode of the component where the directive resides and its child VNodes are all updated.
  • unbind: called only once, when directives are unbound from elements.

Here is a copy of the official website to show some professional. A INSERTED node feels like Mounted, except that bind is null before a INSERTED component renders the DOM tree, and a inserted node has a parent. Update updated componentUpdated Updated componentUpdated Vue3.x update updated componentUpdated

To summary: Bind >> INSERTED >> Update >> componentUpdated >> unbind

They all use the following parameters:

  • el: the element bound by the directive that can be used to manipulate the DOM directly.
  • binding: an 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. Go to the VNode API to learn more.
  • oldVnode: Last virtual node, available only in update and componentUpdated hooks.

Here is also copied from the official website.

Summary: EL is when you write instructions to the tag element, binding is when you need to bind values and so on. Then a Vnode is a Vue that packages the component’s data, method, child and parent components together to create an object.

Finally starting to write code, here is a simple implementation of the V-Model function.

<template>
  <div>
    <input type="text" v-myModel="value" />
    {{ value }}
    <input type="checkbox" v-myModel="checked">
    {{checked}}
  </div>
</template>

<script>
export default {
  directives: {
    myModel: {
      inserted(el, binding, vnode) {
        if ((typeof binding.value) == 'undefined') {
          return console.error('V-myModel not assigned')}// Get the type attribute on input
        const type = vnode.data.attrs.type
        let event = ' '
        let targetValue = ' '
        // Different types have corresponding events and values obtained under the events
        switch (type) {
          case 'text':
            event = 'input'
            targetValue = 'value'
            break;
          case 'textarea':
            event = 'input'
            targetValue = 'value'
            break;
          case 'checkbox':
            event = 'change'
            targetValue = 'checked'
            break;
          case 'radio':
            event = 'change'
            targetValue = 'checked'
            break;
          case 'select':
            event = 'change'
            targetValue = 'value'
            break;

        }
        // binding.value is the value given to v-myModel, where 1 and false are used for page rendering
        el.value = binding.value
        // Assign values to data on the component
        el.addEventListener(event, (e) = > {
          vnode.context[binding.expression] = e.target[targetValue]
        })
      },
    }
  },
  data() {
    return {
      value: '1'.checked: false}}}</script>

Copy the code

I am using the directives option below the component here, and of course I can use global composition using vue. directive(‘ directive name ‘, object/function) what is the difference between a function and an object? Check it out for yourself.

vue3.x

First, the life cycle of the custom instruction:

  • created– new! Called before an element’s attribute or event listener is applied.
  • bind– > beforeMount
  • inserted– > mounted
  • beforeUpdate: new! This is called before the element itself is updated, much like a component lifecycle hook.
  • updateTo remove! There are too many similarities to update, so this is redundant, please use updated instead.
  • componentUpdated– updated
  • beforeUnmount: new! Similar to a component lifecycle hook, it is called before an element is unloaded.
  • unbind -> unmounted

Each life cycle is the same four parameters of vue2. X.

Directly on the code:

<template>
  <div>
    vue3.x
    <input type="text" v-myModel:value="value" />
    {{ value }}
    <input type="checkbox" v-myModel:checked="checked" />
    {{ checked }}
  </div>
</template>

<script lang='ts'>
import { ref } from 'vue'
export default {
  directives: {
    myModel: {
      mounted(el, binding, vnode) {
        if ((typeof binding.value) == 'undefined') {
          return console.error('V-myModel not assigned')}// Get the instance object of the component
        let vm = binding.instance
        // Get the type attribute on input
        const type = vnode.props.type
        let event = ' '
        let targetValue = ' '
        switch (type) {
          case 'text':
            event = 'input'
            targetValue = 'value'
            break;
          case 'textarea':
            event = 'input'
            targetValue = 'value'
            break;
          case 'checkbox':
            event = 'change'
            targetValue = 'checked'
            break;
          case 'radio':
            event = 'change'
            targetValue = 'checked'
            break;
          case 'select':
            event = 'change'
            targetValue = 'value'
            break;
        }
        el.value = binding.value
        // Add a listening event to the element
        el.addEventListener(event, (e) = > {
          Arg is value for v-myModel:value, v-myModel:checked checked, to modify value and checked under the component instance.
          vm[binding.arg] = e.target[targetValue]
        })
      }
    }
  },
  setup() {
    const value = ref('11')
    const checked = ref(false)
    return {
      value,
      checked
    }
  },
}
</script>
Copy the code

In fact, there is a problem here, such as V-myModel :value=”value” if not passed :value in vm, it does not know which value to modify, vUE official introduction of this :value has other functions, I searched many, but did not find a solution, if there is a big guy know for advice.

conclusion

  • Vue2. X User-defined instruction life cyclebind >> inserted >> update >> componentUpdated >> unbind
  • Vue3. X Custom instruction life cyclecreated >> beforeMount >> mounted >> beforeUpdate >> updated >> beforeUnmount >> unmounted
  • Have parameters:el,binding,vnode,oldVnode. The first three are commonly used.