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
- Range object: https://developer.mozilla.org...
- Selection object: https://developer.mozilla.org...
- execCommand method: https://developer.mozilla.org...
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^_^