1.vue3如何实现自定义指令?
Vue 3 中的自定义指令同样使用 directive
函数来创建,下面是一个简单的例子:
const app = Vue.createApp({
data() {
return {
color: 'blue'
}
}
})
// 注册名为 'custom-directive' 的自定义指令
app.directive('custom-directive', {
mounted(el, binding) {
el.style.color = binding.value
}
})
app.mount('#app')
参数解释:
- el : 指令所绑定的元素,可以用来直接操作DOM
- binding : 一个对象
- name:指令名不包含 v- 前缀
- value:指令的绑定值,例如:v-hasPermission =xxx:xxx 中的 xxx:xxx
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdate 钩子中可用无论值是否改变都可用
<template>
<div>
<button v-onceClick="10000" @click="btnClick">ClickMe</button>
</div>
</template>
<script setup>
import {ref} from 'vue';
directives: {
onceClick: {
mounted(el, binding, vnode) {
el.addEventListener('click', () => {
if (!el.disabled) {
el.disabled = true;
setTimeout(() => {
el.disabled = false;
}, binding.value || 1000);
}
});
}
}
}
</script>
2.自定义权限配合按钮使用
<button @click="btnClick" v-hasPermission="['user:list']">查看</button>
2.1参数解释
- v-hasPermission是自定义指令
- ['user:lisyt']是我们设置的对应查看权限标识
2.2全局指令我们一般写在 main.js 中,或者写一个单独的 js 文件然后在 main.js 中引入,下面的例子是直接写在 main.js 中
// main.js
const app = createApp(App);
app.directive('onceClick',{
mounted(el, binding, vnode) {
el.addEventListener('click', () => {
if (!el.disabled) {
el.disabled = true;
setTimeout(() => {
el.disabled = false;
}, binding.value || 1000);
}
});
}
})
2.3实现步骤
1) 用户登录成功时,将用户权限数据,存入sessionStorage
中
// login.vue
<script setup lang='ts'>
import { useStore } from '@/store'
const store = useStore()
const login = ()=>{
// 请求后台接口,拿到相关的用户权限数据
getUserPermissionApi().then(res=>{
sessionStorage.setItem('permission',res.data)
// 示例:
// 页面名称:按钮权限名
// ['auto.add','auto.delete','auto.update']
}).catch(err=>{
console.log('拿到用户权限内容报错了')
})
}
</script>
2) 进行封装,项目根目录下新建一个permission.js
// permission.ts
// 引入vue中定义的指令对应的类型定义
import { directive } from 'vue'
export const permission: directive = {
// mounted是指令的一个生命周期
mounted(el, binding) {
// value 获取用户使用自定义指令绑定的内容
const { value } = binding
// 获取用户所有的权限按钮
const permissionBtn = sessionStorage.getItem('permission')
// 判断用户使用自定义指令,是否使用正确了
if (value && value instanceof Array && value.length > 0) {
const permissionFunc = value
//判断传递进来的按钮权限,用户是否拥有
//Array.some(), 数组中有一个结果是true返回true,剩下的元素不会再检测
const hasPermission = permissionBtn.some((role: any) => {
return permissionFunc.includes(role)
})
// 当用户没有这个按钮权限时,设置隐藏这个按钮
if (!hasPermission) {
el.style.display = 'none'
}
} else {
throw new Error('need roles! Like v-permission="[\'admin\',\'editor\']"')
}
}
}
// 注意,我们这里写的自定义指令,传递内容是一个数组,也就说,按钮权限可能是由
// 多个因素决定的,如果你的业务场景只由一个因素决定,自定义指令也可以不传递一个数组,
// 只传递一个字符串就可以了
main.js中注册为全局指令
import App from './App.vue'
import { createApp, Directive } from 'vue'
import * as directives from '@/directives'
const app = createApp(App)
console.log(directives, 'directives') //打印发现是导出的自定义指令名,permission
Object.keys(directives).forEach(key => { //Object.keys() 返回一个数组,值是所有可遍历属性的key名
app.directive(key, (directives as { [key: string ]: Directive })[key]) //key是自定义指令名字;后面应该是自定义指令的值,值类型是string
})
4) 在页面中使用
<template>
<button v-permission="['user.add']">新增</button>
<button v-permission="['user.update']">编辑</button>
<button v-permission="['user.delete']">删除</button>
</template>
5) 基本完成的全局的自定义权限指令