Custom instructions for Vue3

What is a custom directive

Through the previous study, we all have a certain knowledge of Vue. We all know that we can write our interface in the template tag after the Vue instance is created. When we need to control the display or hiding of a certain dom element, we can use v-if directive. When printing a list in a loop, we can use v-for instructions, etc..., but these instructions are provided by Vue, we can actually define our own instructions, in fact, I understand that this custom instruction is to make a certain function Encapsulate and provide the caller with this instruction. Reduce duplication of the same code. In Vue, custom directives can be defined in two ways: global definition and local definition. Let's see how to define custom directives together.

Example analysis

1. Introduction to basic knowledge

Let's demonstrate Vue's custom commands with a simple example of automatic focus of an input box. The specific scenario is: there is an input box in the interface. When the interface is loaded, let the input box automatically get the focus. Let's look at the general one first. The implementation method, the code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-
    scale=1.0">
    <title>自定义指令</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="root"></div>
</body>
<script>
 const app = Vue.createApp({
      
      
    mounted(){
      
      
        this.$refs.input.focus();
    },
        template: 
        `
        <div>
            <input ref="input"/>
        </div>
        `
    });

    const vm = app.mount('#root');
</script>

运行结果读者可以自己运行看下效果,然后去掉focus函数调用,再运行看效果
refThe way we use attributes in the input box , when the page is loaded, use this.$refs.input.focus(), get inputthe input box, and then call focusthe method to let the input box get the focus.

Although using the above method can meet our needs, it is cumbersome to write, and we need to add focusing logic in the mounted() method of our app instance. Using custom instructions can more easily realize the automatic acquisition of the above input box The focus function, the code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-
    scale=1.0">
    <title>自定义指令</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="root"></div>
</body>
<script>
 const app = Vue.createApp({
      
      
       data(){
      
      
        return{
      
      
            display:true
        	}
       },

        template: 
        `
        <div v-show="display">
            <input v-focus/>
        </div>
        `
    });
    
    // 定义全局的自定义指令
    app.directive('focus',{
      
      
        mounted(el){
      
      
            console.log(el);
            el.focus();
            console.log('mounted');
        }
    });

    const vm = app.mount('#root');
</script>

As shown in the above code, use app.directive('directive name',{xxxx}); to customize the directive, just add the v-directive name to the corresponding dom element when using it, just like this example , the method called is as follows:

 <input v-focus/>

At this time, when you run the code, you will find that the effect is exactly the same as what we did before, and this way of writing is simpler. In the article, we saw the mounted function. Is this function a function of the Vue life cycle? It means that it will be called back when the interface is mounted. The el parameter is the Dom element we use the custom command

 mounted(el){
            console.log(el);
            el.focus();
            console.log('mounted');
        }

In fact, when defining a custom instruction, not only the mounted() function can be rewritten, but other functions can also be rewritten, as shown below:

    app.directive('focus',{
        beforeMount(el){
            console.log('beforeMount');

        },
        mounted(el){
            console.log('mounted');
        },
        beforeUpdate(){
            console.log('beforeUpdate');
        },
        updated(){
            console.log('updated');
        },
        beforeUnmount(){
            console.log('beforeUnmount');
        },
        unmounted(){
            console.log('unmounted');
        }
    });

Run the above code in the browser and open the console, as follows
insert image description here
We can do the corresponding things in the corresponding life cycle callback.

In the above code, we define the custom instruction in a global way. In fact, we also have a local way. The code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-
    scale=1.0">
    <title>自定义指令</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="root"></div>
</body>
<script>
 const direc = {
      
      
      focus:{
      
      
            mounted(el){
      
      
               el.focus();
            }
        }
    };
 const app = Vue.createApp({
      
      
       data(){
      
      
        return{
      
      
            display:true
        }
       },
       directives:direc,
        template: 
        `
        <div v-show="display">
            <input v-focus/>
        </div>
        `
    });
     const vm = app.mount('#root');
</script>

The way to define custom properties using local is:

 const direc = {
      focus:{
            mounted(el){
               el.focus();
            }
        }
    };

Then when using it, you need to add:

 const app = Vue.createApp({
   ...
       directives:direc,
   ...
    });

2. Use custom instructions to change the position of the input box

Next, we use Vue's custom instructions to implement a small function, which is to dynamically change the position of the input box. The code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-
    scale=1.0">
    <title>自定义指令</title>
    <style>
        .header{
      
      
            position: absolute;
        }
    </style>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="root"></div>
</body>
<script>

 const app = Vue.createApp({
      
      
    data(){
      
      
        return{
      
      
            pxValue:50
        }  
    },
        template: 
        `
        <div>
            <div v-pos:left="pxValue" class="header">
            <input />
            </div>
        </div>
        `
    });

    app.directive('pos',{
      
      
        mounted(el,binding){
      
      
            el.style[binding.arg] = binding.value + 'px';

        },
        updated(el,binding){
      
      
            el.style[binding.arg] = binding.value + 'px';
        }  
    });

    // 上面代码等价于下面注释掉的代码

    // app.directive('pos',(el,binding)=>{
      
      
    //     console.log(binding.arg,'binding')
    //     el.style[binding.arg]=(binding.value+'px');
    // })

    const vm = app.mount('#root');
</script>

First, we define a style and use absolute positioning to determine the position of the input box:

    <style>
        .header{
      
      
            position: absolute;
        }
    </style>

Use a pxValue to represent the value of the position of the input box, and then you can
v-pos:left="pxValue"determine whether the input box is from the left or the right or from other reference objects. Then when customizing the command, get the value and value passed from the attribute pxValue, and change the position of the input box:

  app.directive('pos',{
        mounted(el,binding){
            el.style[binding.arg] = binding.value + 'px';

        },
        updated(el,binding){
            el.style[binding.arg] = binding.value + 'px';
        }  
    });

It can also be written as:

   app.directive('pos',(el,binding)=>{
        console.log(binding.arg,'binding')
        el.style[binding.arg]=(binding.value+'px');
    })

Then you can use it as follows:

 <div v-pos:left="pxValue" class="header">
或者  <div v-pos:right="pxValue" class="header">
或者  <div v-pos:top="pxValue" class="header">

After running, you can modify the corresponding value to view the effect, here is left for readers to experience for themselves:
insert image description here

Summarize

This article mainly introduces two ways for Vue to use custom instructions, one is the use of global custom instructions, and the other is the use of local custom instructions. It should be noted that the custom Vue.createApp({directives:局部自定义指令的变量名});command can only be used after the local custom command is defined. Finally, we use an example of dynamically changing the position of the input box to demonstrate the use of custom commands.

Guess you like

Origin blog.csdn.net/zxj2589/article/details/130039011