Vue's detailed instructions and custom instructions

instruction

If you want to understand custom commands, you must first understand what a command is.

The essence of instructions: syntactic sugar, flag bits. In the compile phase render function, the instructions will be compiled into JavaScript code.

Common Vue built-in instructions are:

  • v-on is @. v-on:click="function", abbreviated as @click="function"
  • v-if
  • v-for
  • v-html
  • ……

So instructions are certain events that are bound to our element tags, and when our DOM components trigger corresponding instructions under certain conditions.

custom directive

First look at the official statement of Vue:

In addition to the default built-in directives for core functions (v-model and v-show), Vue also allows registration of custom directives. Note that in Vue2.0, the main form of code reuse and abstraction is components. However, in some cases, you still need to perform low-level operations on ordinary DOM elements, and at this time you will use custom instructions

The customization of instructions means that we write a set of functional functions that can operate on dom according to the rules formulated by Vue, and then they can have certain functional effects like other built-in instructions of Vue. Instructions are equivalent to simplifying our operations on DOM, and can quickly process DOM events. Of course, we should try to minimize the use of some instructions that are easy to consume browser resources.

About registering custom directives

global registration

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
    
    
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    
    
    // 聚焦元素
    el.focus()
  }
})

partial registration

directives: {
    
    
  focus: {
    
    
    // 指令的定义
    inserted: function (el) {
    
    
      el.focus()
    }
  }
}

Hook functions for custom directives

bind: Called only once, when the directive is bound to the element for the first time. One-time initialization settings can be performed here.

inserted: Called when the bound element is inserted into the parent node (only the parent node is guaranteed to exist, but not necessarily inserted into the document).

update: Called when the VNode of the component is updated, but it may happen before the update of its child VNode. The value of the directive may or may not have changed. But you can ignore unnecessary template updates by comparing the values ​​before and after the update (see below for detailed hook function parameters).

componentUpdated: Called after the VNode of the component where the command is located and its child VNodes are all updated.

unbind: Called only once, when the instruction is unbound from the element.

Encapsulate custom directives

Through the above description, I believe that most people probably have a certain understanding of custom commands and commands, and can already start writing some simple and non-repetitive commands. But in the face of some complex custom instructions that may need to be used frequently, at this time we'd better encapsulate the code in one layer, which can facilitate our subsequent modification and hierarchical code writing.

1. First, you can choose to create a new folder directive in the root directory

insert image description here
2. Create a folder for custom instructions.
insert image description here
3. The index.js file under the folder, for example, realizes one-click copying of text content for pasting with the right mouse button.


const copy = {
    
    
  bind(el, {
     
      value }) {
    
    
    el.$value = value
    el.handler = () => {
    
    
      if (!el.$value) {
    
    
        // 值为空的时候,给出提示。可根据项目UI仔细设计
        console.log('无复制内容')
        return
      }
      // 动态创建 textarea 标签
      const textarea = document.createElement('textarea')
      // 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
      textarea.readOnly = 'readonly'
      textarea.style.position = 'absolute'
      textarea.style.left = '-9999px'
      // 将要 copy 的值赋给 textarea 标签的 value 属性
      textarea.value = el.$value
      // 将 textarea 插入到 body 中
      document.body.appendChild(textarea)
      // 选中值并复制
      textarea.select()
      const result = document.execCommand('Copy')
      if (result) {
    
    
        console.log('复制成功') // 可根据项目UI仔细设计
      }
      document.body.removeChild(textarea)
    }
    // 绑定点击事件,就是所谓的一键 copy 啦
    el.addEventListener('click', el.handler)
  },
  // 当传进来的值更新的时候触发
  componentUpdated(el, {
     
      value }) {
    
    
    el.$value = value
  },
  // 指令与元素解绑的时候,移除事件绑定
  unbind(el) {
    
    
    el.removeEventListener('click', el.handler)
  },
}
export default copy

4. Under the directive, there needs to be a file in charge of the global directive, which is convenient for us to perform global registration operations.
directive/index.js


import copy from './copy'

// 自定义指令
const directives = {
    
    
  copy,
}
 
export default {
    
    
  install(Vue) {
    
    
    Object.keys(directives).forEach((key) => {
    
    
      Vue.directive(key, directives[key])
    })
  },

5. Global traversal registration, the main.js.Vue.use function will call the install we wrote, which is equivalent to running the code in our install

import Vue from 'vue'
import Directives from '@/directive'
Vue.use(Directives)

Guess you like

Origin blog.csdn.net/huangzhixin1996/article/details/130285320