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>