preface

Nowadays, Vue occupies a large part of the domestic front-end market, and there are more and more interview questions related to Vue in the front-end job hunting process. A big part of the reason why Vue is so popular is that its ideas of gradualism, componentization, instruction and so on make it very easy for ordinary developers to use it.

The directive is one of the most used things in a Vue project. Today we will explain a branch of the Vue directive: the custom directive.

1. What is a custom directive?

To use a custom directive, first of all we have to figure out what is a custom directive?

The custom instructions are very easy to understand. The V-for, V-IF, V-model and so on that we use are called instructions, also known as the built-in instructions of Vue. These are all instructions that we can use directly.

In order to better meet the needs and maximize the personalized development of developers, Vue exposed the API of custom instructions to us, so that in addition to using built-in instructions, we can also define our own instructions, which are very similar to the way of built-in instructions.

For example, let’s look at the code below:

<p v-pin="200"> </p>Copy the code

The v-pin in the above code may not be known by many friends, it looks like an instruction, but have not encountered. The V-pin is a custom instruction, but we omit the code to register it.

2. Prepare the environment

We used Vue2. X scaffolding tools to quickly build a project for the room.

Build command:

Vue create Project nameCopy the code

Up and running:

3. How to register custom instructions?

To use a custom directive, we have to register it in advance, just like our components.

Registration instructions are also divided into global registration and local registration, and global registration components and local registration components of the same reason. Globally registered directives can be used directly in any component, and locally registered directives can only be used where registered.

3.1 Global Registration

Global registry As the name implies, custom directives are registered and can be used directly within all components of a project.

Vue provides a directive method to register custom directives. We register a global custom directive in main.js.

The code is as follows:

// src/main.js
import Vue from "vue";
import App from "./App.vue";

Vue.config.productionTip = false;
Vue.directive("resize", {
  bind() {},
  inserted() {},
  update() {},
  componentUpdated() {},
  unbind() {},
});
new Vue({
  render: (h) => h(App),
}).$mount("#app");
Copy the code

This method takes two arguments: the name of the directive and the object containing the directive hook function.

After the directive is registered, we can use the directive as a “V-directive name” on any element in the component of the project.

It is important to note that the instruction hook function is not necessary. It can be compared to the vUE lifecycle hook function, which is used to make instructions do different things in different procedures.

3.2 Local Registration

In general, if custom directives are not used by every component, we generally register custom directives.

Let’s modify the app. vue file and register the custom instruction inside it as follows:

<script>
export default {
  name: "App",
  components: {},
  directives: {
    resize: {
      bind() {},
      inserted() {},
      update() {},
      componentUpdated() {},
      unbind() {},
    },
  },
};
</script>
Copy the code

As shown above, Vue provides a caching option for us to register a custom directive, which is at the same level as Data and Methods, and in the previous code we registered a custom directive called Resize, which is only allowed to be used internally in the component.

Note: Global registration directives use directive and local registration directives use directives. Caching Is well understood. Local directives register many at a time and global directives only one at a time.

4. Detailed description of user-defined command parameters

In the previous section, we briefly introduced the local and global registration custom directives. We can see that there are several hook functions in the directive. Our operation logic is mainly in these hook functions, so we need to introduce these hook functions.

4.1 Introduction to hook functions

The bind:

Only called 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 (the parent is guaranteed to exist, but not necessarily inserted into the document).

Update:

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:

Called after the VNode of the component where the directive resides and its child VNodes are all updated.

Unbind:

Only called once, when an instruction is unbound from an element.

The above five are all the hook functions of the custom directive. Each hook function is optional, depending on the situation. Inserted, componentUpdated, componentUpdated, and directive unbind. These are somewhat similar to component lifecycle functions.

4.2 Hook Function Parameters

To facilitate our logic, each hook function takes parameters that we can use to do whatever we want.

El:

The element bound by the directive can be used to manipulate the DOM directly.

Binding:

An object containing the following properties:

  • name: Indicates the command namev-Prefix.
  • value: The binding value of the directive, for example:v-my-directive="1 + 1", the binding value is2.
  • oldValue: The value preceding the instruction binding, only inupdatecomponentUpdatedHooks are available. Available regardless of whether the value changes.
  • expression: Command expression in the form of a string. For example,v-my-directive="1 + 1"Where, the expression is"1 + 1".
  • arg: Optional parameter passed to the instruction. For example,v-my-directive:fooWhere, the parameter is"foo".
  • modifiers: an object that contains modifiers. Such as:v-my-directive.foo.bar, the modifier object is{ foo: true, bar: true }.

Vnode:

Virtual nodes generated by Vue compilation.

OldVnode:

Last virtual node, available only in update and componentUpdated hooks.

The EL and binding parameters are the most mundane ones that we use to make things easier.

5. Simple case combat

This section describes how to register a custom directive and its parameters. In APPVue, we define a custom directive and verify the implementation of the hook function.

The code is as follows:

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" />
    <div v-resize></div>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},
  directives: {
    resize: {
      bind() {
        console.log("bind")
      },
      inserted() {
        console.log("inserted")
      },
      update() {
        console.log("update")
      },
      componentUpdated() {
        console.log("componentUpdated")
      },
      unbind() {
        console.log("unbind")
      },
    },
  },
};
</script>
Copy the code

The effect is as follows:

In the code above we bind the custom directive resize to the div element, and when we refresh the page, we execute the bind and INSERTED hook functions of the custom directive, and the rest of the functions will not be executed until the element is updated.

5.1 Implementing the V-resize command

Demand Background:

When doing large data screens or adaptive development, we often need to rerender the page based on the browser window size, such as redrawing echarts charts.

Requirement Description:

Implement custom instruction V-resize instruction, when the window size changes, real-time printing of the latest window width and height.

Code implementation:

// SRC/app. vue <template> <div id=" APP "> <h1> Window width: {{innerWidth}} {{ innerHeight }}</h1> <div style="height: 300px; width: 80%; background: blue" v-resize></div> </div> </template> <script> export default { name: "App", data() { return { innerHeight: window.innerHeight, innerWidth: window.innerWidth, }; }, components: {}, directives: { resize: { bind() { console.log("bind"); }, inserted(el, binding, vnode) { console.log("inserted"); console.log(el, binding); let that = vnode.context; // Listen for the browser's resize event window.adDeventListener ("resize", () => {that.innerheight = window.innerheight; that.innerWidth = window.innerWidth; }); }, update() {console.log("VNode is updated "); }, componentUpdated() { console.log("componentUpdated"); }, unbind() { console.log("unbind"); window.removeEventListener("resize"); }},}}; </script>Copy the code

The effect is as follows:

When we change the size of the browser window, the page will print the latest height and width in real time. Of course, this is only a simple case, in real projects we will usually call some custom methods after the window size changes.

5.2 Instruction parameter and value Transfer

When we use v-bind, V-model and other built-in instructions, parameters and values can be passed, and so can our custom instructions.

Sample code:

<template> <div id="app"> <h1> Window width: {{innerHeight}}</h1> <div style="height: 300px; width: 80%; background: blue" v-resize:[args]="value" ></div> </div> </template> <script> export default { name: "App", data() {return {innerHeight: window.innerHeight, innerWidth: window.innerWidth, args: "I am an argument ", value: "I am a passable value ",}; }, components: {}, directives: { resize: { bind(el, binding) { console.log("bind"); The console. The log (" value ", the binding. Value); Console. log(" parameters ", binding.arg); }},}}; </script>Copy the code

The effect is as follows:

Args and value are the parameters and values we pass to the instruction. Note that value receives a variable or expression, and arg receives a string or variable.

5.3 Instruction abbreviations

Most of the time we do not need to use all of the hook functions in a custom directive. There are only a few commonly used hook functions, so we are provided with a shorthand method.

The code is as follows:

Resize (el, binding) {console.log(" I am a shorthand custom directive ", binding.value); },Copy the code

The bind and update hook functions are combined into one, which is usually used when we want the two hook functions to do the same thing.

6. Customize command usage scenarios

Now that we know how to use custom instructions, we can expand our usage scenarios and deepen our understanding of custom instructions.

6.1 v – copy

One – key copy text content, used for right mouse paste.

6.2 v – longpress

To achieve long press, the user needs to press and hold the button for several seconds to trigger the corresponding event.

6.3 v – debounce

To prevent the button from being clicked multiple times in a short period of time, use the anti-shake function to limit the button to one click in a specified period of time.

6.4 v – the LazyLoad

Implement an image lazy loading directive that only loads images in the visible area of the browser.

6.5 v – draggable

Implement a drag-and-drop instruction that can drag and drop elements anywhere in the viewable area of the page.

Some of the above custom instructions are very common in the requirements, the corresponding instruction code is also a lot of online, but I suggest you go down to practice.

conclusion

The syntax rules and usage of custom instructions are simple, but the complexity is what problem we are trying to solve. Using the right solution in the right situation is the most important.