vue的自定义指令以及封装实用案例

本文详细介绍了Vue中的内置指令如v-model和v-for,以及如何创建自定义指令进行DOM操作。重点讲解了自定义指令的分类(局部和全局),生命周期的不同阶段,以及如何在指令中传递参数和处理时间戳转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.vue的指令

我们了解的vue指令有: v-model,v-show,v-for等,除了这些指令,我们也可以实现自己的自定义指令。在vue中代码的抽取和复用主要是通过组件,如果我们想要对DOM元素进行底层操作,可以通过自定义组件来完成。

2.自定义指令的分类

自定义局部指令:在options api选项中的directives中设置。
自定义全局指令:在app的directive方法。

举例:使用自定义指令实现自动获取焦点

正常情况下:

通过ref拿到input标签,然后使用生命周期函数的回调,执行input标签的focus的操作

<template>
    <input type="text" ref="inputRef">
  </template>
  
  <script>
  import { ref, onMounted } from "vue";
  
  export default {
    setup() {
      const inputRef = ref();
      onMounted(() => {
        // 在组件挂载后,通过 inputRef.value 访问引用的输入框元素
        inputRef.value.focus()
        console.log(inputRef.value);
      });
  
      return {
        inputRef,
      
      };
    },
  };
  </script>
  
局部自定义:v-focus

directives声明focus方法的内容(前面不用加上v-的前缀)

<template>
    <input type="text" v-focus>

  </template>
  
  <script>
  export default {
    directives:{
        focus:{
            mounted(el){
                el.focus()
            }
        }
    }
  };
  </script>
  

同理全局声明也是一样,两者格式有些区别!!!

全局自定义:v-focus

在app中存在directive,可以在上面设置全局指令。

import { createApp } from "vue/dist/vue.esm-bundler";
import app from "./自定义指令/app.vue"

const myapp= createApp(app);
myapp.directive("focus",{
        mounted(el){
            el.focus()
        }
    }
)
myapp.mount("#app");

3.指令的生命周期

created:在绑定元素的attribute或者事件监听器之前被使用
beforeMount:当指令第一次绑定元素,并且挂载父组件之前被使用。
mounted:在绑定元素的组件被挂载后调用。
beforeUpdate:在指令绑定的组件更新其Vnode之前被调用
updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用

4.生命周期的参数

<template>
    <input type="text" v-focus>
  </template>
  <script>
  export default {
    directives:{
        focus:{
            mounted(el,bindings,vnode,proVnode ){
                console.log("el:",el)
                console.log("bindings:",bindings)
                console.log("vnode:",vnode)
                console.log("preVnode:",proVnode)
            }
        }
    }
  
  };
  </script>
el:表示当前的元素
bindings:可以从中取出一些参数的内容
vnode:可以获取当前的vnode节点。
preVnode:可以获取之前的vnode节点。

参数的补充属性

可以给方法绑定数据

例如传入一个字符串时:v-focus=""

如果要传入一个字符串,则字符串还需要添加一个冒号

v-focus="'coder'",这个值存在bindings的value中
添加修饰词:v-focus.aaaa
这个值存在bindings的modifiers
<template>
    <input type="text" v-focus.aaaa="'coder'">

  </template>
  
  <script>
  export default {
    directives:{
        focus:{
            mounted(el,bindings){
                console.log(bindings)
            }
        }
    }
  };
  </script>
  

案例:对时间戳进行转换

对日期进行格式化的js库

npm install dayjs
1.time-format.js写相关的directive注册,用的是全局自定义的写法

time-format.js

import dayjs from "dayjs"

export default function formatTime (myapp){
  myapp.directive("time-format",{
    mounted(el,bindings){
        let format=bindings.value
        if(!bindings.value){
            //如果没有传入格式要求,就使用默认的格式
            format="YYYY-MM-DD-HH-MM"
        }
        const time=el.textContent
        const datatime=parseInt(time)
        //在某些编程语言和应用中,时间戳以秒为单位,但在其他情况下,时间戳可能以毫秒为单位。
        //如果你得到的时间戳长度为 10,那么它很可能是以秒为单位的。
      	//为了将其转换为毫秒,你需要将其乘以 1000。
        if(datatime.length===10){
            datatime=datatime*1000
        }
        //format内部的是转换的格式
        el.textContent=dayjs.unix(datatime).format(format);
         
      }
  })

}
2.建立一个专门的directives文件夹,在内部写一个出口文件,并且接受time-format的方法传入

index.js

在内部定义了一个总方法register,再把它传到js全局文件中

之后如果还有新的方法,编写好后直接import传入到index.js中,然后总方法register中使用就好了

此时的这些myapp只是形参,真正全局myapp是在index.js全局文件中

import formatTime from "./time-format";

export default function register(myapp) {
    formatTime(myapp)
}
3.directive传入全局js文件,全局自定义注册

从directives文件夹中传入的register方法,在index.js中正式全局自定义注册使用,传入全局对象myapp,

myapp最终是传入到time-format.js文件中,进行相关的全局自定义代码书写

import { createApp } from "vue/dist/vue.esm-bundler";
import app from "./自定义指令/app.vue"
import register from "./directives";

const myapp= createApp(app);
register(myapp)
myapp.mount("#app");
在相关页面直接使用
<template>
   <div v-time-format="'YYYY年MM月DD日HH:MM'">{{ timetamp }}</div>

  </template>
  
  <script>
  export default {
    setup(){
        const timetamp=1624452193

        return {
            timetamp
        }
    }
  
  };
  </script>
  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值