VUE3--自定义指令实现按钮级权限控制(vite2+vue3.2.x)
概要
vue除了核心功能默认内置的指令 (例如 v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
初始化项目
使用npm执行以下命令:
npm init vite@latest
按照操作提示进行操作即可
配置vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'public': path.resolve(__dirname, './public')
}
}
})
按照下图创建目录结构:
配置vuex用到的角色数据
user.js代码
const state = {
roles: ['role1', 'role2']
}
export default {
namespaced: true,
state
}
getters.js代码
const getters = {
roles: state => state.user.roles
}
export default getters
index.js代码
import { createStore } from 'vuex'
import getters from './getters'
// 相当于webpack中的require.context的作用
const modulesFiles = import.meta.globEager('./modules/*.js')
const modules = Object.keys(modulesFiles).reduce((modules, modulePath) => {
// 正则匹配文件名称
const moduleName = modulePath.replace(/^\.\/modules\/(.*)\.\w+$/, '$1')
const value = modulesFiles[modulePath]
modules[moduleName] = value.default
return modules
}, {})
// 创建store实例
const store = createStore({
modules,
getters
})
export default store
开发自定义指令功能
permission.js代码
import store from '@/store'
const checkPermission = (el, binding) => {
const { value } = binding
const roles = store.getters && store.getters.roles
if (value && value instanceof Array) {
if (value.length > 0) {
const elRoles = value
const hasPermission = roles.some(role => {
return elRoles.includes(role)
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
}
} else {
throw new Error(`need a array like ['role1', 'role2']`)
}
}
export default {
mounted (el, binding) {
checkPermission(el, binding)
},
updated (el, binding) {
checkPermission(el, binding)
}
}
index.js代码
import permission from './permission'
const install = function (app) {
app.directive('permission', permission)
}
if (window.Vue) {
window['permission'] = permission
Vue.use(install)
}
permission.install = install
export default permission
全局注册store和permission指令
main.js代码如下
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
import permission from './directive/permission'
const app = createApp(App)
app.use(store)
app.use(permission)
app.mount('#app')
调用指令
App.vue代码如下, 运行npm run dev查看 demo 效果
<template>
<h1>Hello Vite</h1>
<h2>当前角色{{ roles }}</h2>
<button>无v-permission</button>
<button v-permission="['role3']">有v-permission</button>
</template>
<script setup>
import { computed } from "@vue/reactivity"
import store from "./store"
const roles = computed(() => store.getters.roles)
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>