vue3页面权限以及按钮权限

最近再写一个vue3项目中,需要涉及页面以及按钮权限,在此做一个简单的记录。

一、页面权限:

有两种方案可以实现(本文采用的第二种方式):

1、匹配角色路由后,通过vue-router中的addRoutes方法添加。

2、在sidebar组件中使用工具函数,通过meta中定义的code与后端返回的codeList做对比,没有则隐藏菜单。

sidebar.vue

<template>
  <div :class="{ 'has-logo': showLogo }">
    <Logo v-if="showLogo === '1'" :collapse="isCollapse" />
    <el-scrollbar wrap-class="scrollbar-wrapper">
      <el-menu
        :default-active="activeMenu"
        :collapse="isCollapse"
        unique-opened
        :collapse-transition="false"
        mode="vertical"
        @select="menuSelect"
      >
        <sidebar-item
          v-for="route in routes"
          :key="route.path"
          :item="route"
          :base-path="route.path"
        />
      </el-menu>
    </el-scrollbar>
  </div>
</template>

<script lang="ts">
  import { computed, defineComponent, ref, onBeforeMount } from 'vue'
  import { useRoute, useRouter } from 'vue-router'
  import { useStore } from 'vuex'
  import SidebarItem from './SidebarItem.vue'
  import { algorithm } from '../../../utils/algorithm'
  import { useDynamicRoutesHook } from '../tag/tagsHook'
  import { emitter } from '~@/utils/mitt'
  import Logo from './Logo.vue'
  import { storageLocal, storageSession } from '~@/utils/storage'
  import { authAllot } from '~@/utils'

  export default defineComponent({
    name: 'Sidebar',
    components: { SidebarItem, Logo },
    setup() {
      // 调用工具函数authAllot方法,设置菜单
      const router = authAllot(storageSession.getItem('auth'))

      const store = useStore()

      const route = useRoute()

      const showLogo = ref(storageLocal.getItem('logoVal') || '1')

      const activeMenu = computed(() => {
        const { meta, path } = route
        if (meta.activeMenu) {
          return meta.activeMenu
        }
        return path
      })

      const { dynamicRouteTags } = useDynamicRoutesHook()

      const menuSelect = (indexPath: string): void => {
        let parentPath = ''
        let parentPathIndex = indexPath.lastIndexOf('/')
        if (parentPathIndex > 0) {
          parentPath = indexPath.slice(0, parentPathIndex)
        }
        // 找到当前路由的信息
        function findCurrentRoute(routes) {
          return routes.map((item, key) => {
            if (item.path === indexPath) {
              dynamicRouteTags(indexPath, parentPath, item)
            } else {
              if (item.children) findCurrentRoute(item.children)
            }
          })
          return
        }
        findCurrentRoute(algorithm.increaseIndexes(router))
        emitter.emit('changLayoutRoute', indexPath)
      }

      onBeforeMount(() => {
        emitter.on('logoChange', (key) => {
          showLogo.value = key
        })
      })

      return {
        routes: computed(() => algorithm.increaseIndexes(router)),
        activeMenu,
        isCollapse: computed(() => !store.getters.sidebar.opened),
        menuSelect,
        showLogo
      }
    }
  })
</script>

authAllot工具函数

/**
 * @description: 根据code或者拼接规则设置菜单权限
 * @param { any } authList
 * @return { Array }
 */
export const authAllot = (authList: any[]) => {
  const router = XEUtils.clone(useRouter().options.routes, true)
  const mapRouter = (routes: any) => {
    if (Object.prototype.toString.call(routes) === '[object Array]') {
      return routes.reduce((result: any[], route: any) => {
        if (route.meta && !route?.meta?.code) route.meta.code = route?.path
        const code = route.meta?.code
        if (code) {
          const allow: any = authList.findIndex((auth: any) => auth.code === code)
          if (allow == '-1') {
            route.meta && (route.meta.hidden = true)
          }
        }
        if (route?.children?.length && code) {
          route?.children.forEach((_: any) => {
            if (!_?.meta?.code) {
              !_.path.includes('/')
                ? (_.meta.code = route.meta.code + '/' + _.path)
                : (_.meta.code = route.meta.code + _.path)
            }
          })
          mapRouter(route.children)
        }
        return [...result, route]
      }, [])
    } else {
      return []
    }
  }
  return mapRouter(router)
}

二、按钮权限:

使用自定义命令实现

import { storageSession } from '~@/utils/storage'

const directives = [
  {
    name: 'permission',
    value: {
      mounted(el: any, binding: any) {
        const type = binding.value || ''
        let status = false
        // 获取当前角色codeList
        const permissionBtns = storageSession.getItem('auth')
        permissionBtns.forEach((item: any) => {
          if (type == item.code) {
            status = true
          }
        })
        // 没有匹配则隐藏按钮
        if (!status) {
          el.style.display = 'none'
        }
      }
    }
  }
]

export const useDirectives = (app: any) => {
  directives.forEach((directive) => app.directive(directive.name, directive.value))
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3 中,你可以通过自定义指令或组件的方式来封装权限菜单和权限按钮。 1. 自定义指令 你可以通过自定义指令来实现权限按钮的封装。例如,你可以创建一个名为 `v-permission` 的指令,然后在需要控制权限按钮上使用该指令。在指令中,你可以通过判断用户是否拥有相应的权限来控制按钮的显示或隐藏。 示例代码: ```vue <template> <button v-permission="'edit'">编辑</button> </template> <script> export default { directives: { permission: { mounted(el, binding) { const permission = binding.value; const hasPermission = checkPermission(permission); if (!hasPermission) { el.style.display = 'none'; } } } } } </script> ``` 2. 组件 你也可以通过组件的方式来封装权限菜单和权限按钮。例如,你可以创建一个名为 `PermissionMenu` 的组件,然后在该组件中根据用户是否拥有相应的权限来动态生成菜单。 示例代码: ```vue <template> <ul> <li v-for="item in menu" :key="item.path"> <router-link v-if="hasPermission(item.permission)" :to="item.path">{{ item.title }}</router-link> </li> </ul> </template> <script> export default { data() { return { menu: [ { path: '/', title: '首页', permission: 'home' }, { path: '/user', title: '用户管理', permission: 'user' }, { path: '/role', title: '角色管理', permission: 'role' } ] } }, methods: { hasPermission(permission) { return checkPermission(permission); } } } </script> ``` 无论是自定义指令还是组件,都需要在代码中实现权限的判断逻辑,以保证权限的正确控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值