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>

posted @ 2021-09-13 22:12  Elwin0204  阅读(614)  评论(0编辑  收藏  举报