The use of vue custom instructions ~ taking the imitation of v-show and the implementation of v-copy as an example

Background of vue custom instruction generation

  • We know that all kinds of code written by front-end programmers will eventually act on DOM elements on the page. For example, fix the basic structure of DOM with HTML, set the style of DOM with CSS, and do some DOM interaction with JS. Because the DOM element is equivalent to the "physical layer", it should be presented to the user. DOM is equivalent to a building block. We operate this building block and finally "build" it into various effects.

    Therefore, all the fancy front-end frameworks are encapsulated based on the front-end three piece set of HTML, CSS and JS

  • Therefore, it is convenient to directly operate DOM through the $symbol in jQuery. However, direct operation of DOM will cause page reflow and redrawing, which will slightly waste the browser's performance. It is easy to get stuck on the page, resulting in poor user experience.

    Everything has its advantages and disadvantages. Direct operation of DOM is sometimes, or may be, a simple, convenient and fast choice.

  • Therefore, vue and react are on the stage. With the idea of data-driven, they do not directly operate the dom. They do a buffer through the virtual dom. The virtual DOM will collect who needs to operate the DOM and what has operated the dom. They will be recorded first, and finally all operate the DOM together. It feels like js document fragments. In this way, the browser performance will be optimized and improved a lot. Therefore, direct operation of DOM is not advocated in vue, because with virtual DOM, why do you directly operate real DOM. Use vue instructions

    Virtual DOM is really a good thing. Praise the boss. We know that the built-in instructions provided by vue are very convenient and can solve most DOM operation problems, but they can not solve all problems.

  • So in some cases, Vue built-in instructions can not meet our needs. What should we do. Of course, the founder of Vue also thought of this problem, so he made Vue user-defined instructions and encapsulated a set of rules for hook functions and corresponding parameters for us to use, so as to solve the corresponding problems more conveniently

    vue user-defined instructions directly operate the DOM. In some scenarios, vue user-defined instructions are a good choice

Classification of vue custom instructions

There are two kinds of vue custom instructions

  • 1. Global custom instruction (global registration required)
  • 2. Component customization instruction (internal component registration is required)

In fact, a user-defined instruction is an object. There are some hook functions on the object. The hook function on the user-defined instruction object is similar to the life cycle hook function of vue component. It will be described later through cases

Generally, there will be more global user-defined instructions. After all, it is convenient to reuse

Explanation of vue user defined instruction

Case 1 El input initial focus acquisition (component customization instruction)

This case is actually a case on the official website. Let's modify it here to make it easier for us to understand.

Suppose we need such an effect: after the page is loaded, the El input box automatically obtains the focus, which is similar to that after Baidu opens the page, the input box automatically obtains the focus.

<template>
  <div>
    <!-- Hang instruction on element -->
    <el-input v-myFocus></el-input>
  </div>
</template>

<script>
export default {
  name:"myCode"
  // This example is a local custom instruction, so the directives are written inside the component
  directives: {
    // Name the instruction myFocus
    myFocus: {
      inserted: function (el) { // The inserted hook is when this element is about to be inserted into the document. The specific order is after created and before mounted. You can see the print order
                        // The El parameter is: the custom is written on who and hung on the DOM element. This el is the DOM element object. The hook function has other parameters, which will be described later
        console.log("Custom instruction-->", el.childNodes);
        // Let's focus on the element first. El input is wrapped around the native input. Therefore, we need to take the child element through the native js and find the input. See the print results for details
        el.childNodes[1].focus(); // Execute the focus method of the native input
      },
    },
  },
  created() { console.log("created-->") },
  mounted() { console.log("mounted-->") }
}
</script>

For demonstration, copy and paste the code directly

Case 2: copy v-show function (Global user-defined instruction)

The renderings are as follows

After looking at the rendering, the function is actually no different from that of v-show. Taking such an example is convenient to better understand vue user-defined instructions

First, create a new utils folder to store the index.js file, which is used to write global customization instructions

// Introduce vue and use the directive method of vue to register a custom instruction
import Vue from 'vue'
Vue.directive('showshow', { // The name of the instruction is show
    // The bind function is generally used to initialize data and bind events
    bind(el, binding, vnode) {
        console.log(el, binding.value, vnode);
        // The el parameter is the element of the currently used instruction, the bind parameter is the data bound by the instruction, and vnode is the virtual dom
        const flag = binding.value // The ID of the binding in the component was found
        if (flag == false) {
            el.style.display = 'none'
        } else {
            el.style.display = 'inline-block'
        }
    },
    // The inserted function is called when an element is inserted into a dom node
    inserted(el, binding, vnode) { },
    // Both update and componentUpdated are used for updating, but the former is more commonly used. The oldVnode parameter is only available in these two hooks
    componentUpdated(el, binding, vnode, oldVnode) { },
    update(el, binding, vnode, oldVnode) {
        const flag = binding.value
        if (flag == false) {
            el.style.display = 'none'
        } else {
            el.style.display = 'inline-block'
        }
    },
    // unbind is used when unbinding, for example, to remove the event bound in the first bind function
    unbind(el, binding, vnode) { }
});

The second step is to introduce the file for writing global user-defined instructions in main.js (indicating that it is used)

import Vue from 'vue'
import App from './App.vue'
import router from "@/router/index.js" //Import routing table
import store from './store/index' // Introducing vuex
// ...

// You can use global custom instructions after importing^_^
import './views/utils/index.js'

let vvvue = new Vue({
  render: h => h(App),
  router,
  store // Mount it
}).$mount('#app')

The third step is to use the global custom instruction in the component

<template>
  <div>
    <el-button @click="change" type="primary">Show hide Toggle</el-button>
    <!-- 
        Add this button vue Custom instructions for v-showshow ,And let this custom instruction bind vue In component data Data
        So what's bound here is isShowBtn Logo, which controls display and hiding
    -->
    <el-button type="primary" plain v-showshow="isShowBtn">Imitation writing v-show Button</el-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShowBtn: true, // Initially true, let it display
    };
  },
  methods: {
    // Click to switch display and hide back and forth
    change() { this.isShowBtn = !this.isShowBtn },
  },
};
</script>

Some Taoist friends say, clams? Isn't that unnecessary? Not really, because I haven't encountered a specific scene yet. The above two examples are mainly to learn the idea of user-defined instructions. Next, let's take a small example. Click the text one click Copy function.

Case 3 implementation of v-copy custom instruction

design sketch

Click to copy successfully, and then execute Ctrl V at the corresponding position on the computer to paste the clicked text directly

The first step is to write custom instruction code

import Vue from 'vue'
Vue.directive('copy', { // The name of the instruction is v-copy
    // bind function initialization
    bind(el, binding, vnode) { },
    // The inserted function is called when an element is inserted into a dom node
    inserted(el, binding, vnode) {  // The el parameter is the element of the currently used instruction, the bind parameter is the data bound by the instruction, and vnode is the virtual dom
        // Hang the copyFn function on el for easy use
        el.copyFn = () => {
            console.log('Which one did you click DOM', el);
            //Create selected range
            var range = document.createRange();

            // Select the dom you clicked on
            range.selectNode(el);

            //Remove the content in the clipboard. If this statement is not added, it cannot be copied in ie and Edge
            window.getSelection().removeAllRanges();

            //Copy the text content in el to the clipboard
            window.getSelection().addRange(range);

            // Enable copy and paste
            let flag = document.execCommand('copy');

            // Compatibility issues to be noted
            flag ? alert('Copy successfully, you can paste it') : alert('The current browser does not support one click Copy function. Please copy and paste manually')
        }
        el.addEventListener('click', el.copyFn)
    },
    // Both update and componentUpdated are used for updating, but the former is more commonly used
    // The oldVnode parameter is only available in these two hooks, and the DOM before and after the update will be available after the update
    componentUpdated(el, binding, vnode, oldVnode) {
        console.log('componentUpdated');
    },
    update(el, binding, vnode, oldVnode) {
        console.log('update');
    },
    // unbind is used when unbinding, for example, to remove the event bound in the first bind function
    unbind(el, binding, vnode) {
        el.removeEventListener('click', el.copyFn)
    }
});

/**
 * In order to get started quickly, we can simply understand the custom instruction hook.
 *
 * bind Similar to the inserted hook -- >, the created and mounted hooks
 * componentUpdated Similar to update hook -- > updated hook
 * unbind Hooks are similar to -- > destroyed hooks
 *
 * You can copy the code and print it after running, which is more convenient and accurate to understand
 * */

The second step is to use in the. vue file

<template>
  <div>
    <!-- Add to each item v-copy Custom instruction -->
    <div class="item" v-copy v-for="(item, index) in arr" :key="index">{{ item }}</div>
  </div>
</template>

<script>
export default {
  name: "TestVue",
  data() {
    return {
      arr: ["Sun WuKong", "Zhu Bajie", "Sand monk", "Tang Monk"],
    };
  },
};
</script>

<style lang="less" scoped>
.item {
  margin-top: 12px;
  font-size: 24px;
  font-weight: bolder;
  cursor: pointer;
}
</style>

Supplement the knowledge in the case

Regarding MDN's question that the execCommand method may be deleted in the future, whether there is a good answer is also attached: https://segmentfault.com/q/10...

summary

When do I need custom instructions?

When the built-in instructions are not enough, when some special effects need to be done, and when the underlying operation needs to be carried out on ordinary DOM elements

Custom instructions are close to the native js writing method. We can use its hook function and corresponding parameters reasonably to achieve more flexible effect functions. After all, although vue provides a lot of built-in instructions for us to use directly and get started quickly, it also limits some divergent thinking of programmers. Each has its own advantages and disadvantages, so it needs to be weighed^_^

Tags: Vue.js

Posted on Fri, 12 Nov 2021 14:40:31 -0500 by The Jackel