vue自定义指令(directive)
一、directive自定义指令
vue中有v-if,v-for等一系列的方便快捷的指令。我们也可以自定义指令.
自定义指令可以提取出原生DOM操作的逻辑。所以指令的应用范围主要表现在,当一些操作涉及到 DOM 底层时,而且操作逻辑可能用于多处地方,就适合用指令来封装这些逻辑。
vue3指令的钩子函数
- created元素初始化的时候
- beforeMount指令绑定到元素后调用 只调用一次
- mounted元素插入父级dom调用
- beforeUpdate元素被更新之前调用
- update这个周期方法被移除改用updated
- beforeUnmount在元素被移除前调用
- unmounted指令被移除后调用,只调用一次
指令的命名方式
以vNameOfDirective的形式来命名本地自定义指令,以使得它们可以直接在模板中使用。
<template><div><button @click="flag=!flag">切换</button><!-- 给自定义指令传参数、修饰符、值 --><!-- 加v-if用来触发beforeUnmount和unmounted --><!-- <A v-if="flag" v-move:aaa.kangyun="{background: 'red'}"></A> --><!-- 值中的数据变化就会触发beforeupdate, updated --><A v-move:aaa.kangyun="{background: 'red', flag: flag}"></A></div>
</template><script setup lang="ts">
import A from './components/A.vue'
import { ref, Directive, DirectiveBinding } from 'vue'
let flag = ref<boolean>(true)
type Dir = {background: string
}
const vMove: Directive = {created(...args:Array<any>){console.log(args)console.log('created')},// dir相当于我们传过来的参数// type Dir方便我们推导出来backgroundbeforeMount(el: HTMLElement, dir: DirectiveBinding<Dir>){console.log('beforeMount')console.log(dir.value.background)el.style.background = dir.value.background},// 自定义指令传过来的数据在任何一个钩子函数中都可以接收到mounted(){console.log('mounted')},beforeUpdate(){console.log('beforeUpdate')},updated(){console.log('updated')},beforeUnmount(){console.log('beforeUnmount')},unmounted(){console.log('unmounted')}
}
</script><style scoped>
</style>
二、函数简写
在mounted和updated时触发相同的行为,而不关心其他的勾子函数,可以通过这个函数模式实现
封装一个按钮级别的鉴权指令
<template><div><button v-is-show="'user-edit'">添加</button><button v-is-show="'user-create'">编辑</button><button v-is-show="'user-delete'">删除</button></div>
</template><script setup lang="ts">
import type { Directive } from "vue";// 模拟从后台获取到用户的ID并存入localStorage中
localStorage.setItem("userId", "yhdlj");
// 从后台获取用户的ID及相关模组的权限
const permission = ["yhdlj-user-edit",// 如果没有返回相关的权限按钮将不会显示"yhdlj-user-create","yhdlj-user-delete",
];
const userId = localStorage.getItem("userId");
const vIsShow: Directive<HTMLElement, string> = (el, dir) => {if (!permission.includes(`${userId}-${dir.value}`)) {el.style.display = "none";}
};
</script><style scoped></style>