vue3中基于路由层面和组件层面进行用户角色及权限控制的方法解析

文章目录

      • 一、权限控制
      • 二、路由层面控制
      • 三、组件层面控制
        • 1、使用自定义指令
        • 2、使用方法控制
        • 3、封装一个权限控制组件来实现组件层面控制权限
          • 3.1、组件页面 Authority.vue
          • 3.2、使用页面 app.vue
          • 3.3、效果预览

一、权限控制

随着前端技术的不断发展,越来越多的前端框架被使用在 Web 应用程序中,其中尤为出色的一个就是 Vue。Vue 是一个易于理解并且使用方便的框架,它被广泛地应用于 Web 应用程序的开发中。在大多数 Web 应用程序中,权限控制是至关重要的一部分,如何在 Vue 中进行权限控制就成为了一个十分关键的问题。

权限控制是一个很重要的概念,在 Web 应用程序中尤其重要。简单地说,权限控制就是将用户分为不同的分类,为每个分类分配相应的用户权限。这样,用户就只能访问他们所允许的内容了。权限控制可以提高应用程序的安全性和稳定性,使数据更加安全可靠。

在 Vue 中进行权限控制,通常有两种方式:第一种是在路由层面进行控制,第二种是在组件层面进行控制。

用户登录后该用户的角色与权限信息会一同返回给前端,前端将这些信息存储到状态管理里备用即可。

  • 这里使用pinia存储当前用户的角色及权限。你可以根据实际情况进行相应的调整。

  • store/index.js

import { defineStore } from 'pinia'
import { ref } from 'vue';

export const userPermissionsStore = defineStore('userPermissions', () => {
  // 角色
  const roles = ref('admin')

  // 权限
  const userPermissions = ref([])

  //是否登录
  const isLogin = ref(false)

  // 设置状态(传入的权限信息赋值给该状态)
  const setUserPermissions = (params) => {
    userPermissions.value = params
  }

  return {
    isLogin,
    userPermissions,
    roles,
    setUserPermissions
  }
})

二、路由层面控制

在路由层面进行控制,可以在路由的元数据 meta 中设置用户权限,然后可以在路由守卫函数中进行校验。如果当前用户的权限符合该路由的要求,则策略继续进行,否则将导航到其他页面。

路由的元数据 meta 中设置了 requireAuth 和 roles 两个属性,requireAuth 表示该路由需要用户登录才能访问,roles 表示受访问限制的角色。可以在 beforeEach 路由守卫函数中校验用户权限,如果用户有访问该路由的权限,则进入页面,否则跳转到其他页面。这样,就可以在路由层面进行权限控制了。

import { createRouter, createWebHashHistory } from 'vue-router'
import { userPermissionsStore } from '@/store/index'
import { storeToRefs } from 'pinia'

let routes = [{
  path: '/home', // 路径
  name: 'home', // 路由名称
  component: () => import('../views/home.vue'),
  meta: {
    requireAuth: true, // 需要用户权限
    roles: ['admin', 'guest'] // 受访问限制的角色
  }
}, {
  path: '/login', 
  name: 'login', 
  component: () => import('../views/login.vue')
}, {
  path: '/denied', 
  name: 'denied', 
  component: () => import('../views/denied.vue')
}]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

// 添加路由前置守卫
router.beforeEach((to, from, next) => {
  const store = userPermissionsStore()
  // 获取当前登录状态及用户角色
  const { isLogin, roles } = storeToRefs(store)
  // 判断该路由是否需要登录权限
  if (to.meta.requireAuth) {
    // 如果需要,则校验用户是否已经登录
    if (isLogin.value) {
      // 判断当前用户是否有访问该路由的权限
      if (to.meta.roles.includes(roles.value)) {
        next() // 用户有访问权限,直接进入页面
      } else {
        next('/denied') // 跳转到其他页面
      }
    } else {
      // 如果用户未登录,则跳转到登录页面
      next('/login')
    }
  } else {
    next() // 如果不需要登录权限,直接进入页面
  }
});

export default router

三、组件层面控制

1、使用自定义指令

可以利用 Vue 的指令来控制组件的显示和隐藏。例如,可以为每个组件设置一个权限属性,然后在指令中判断当前用户是否有访问该组件的权限,如果有,则显示组件,否则隐藏组件。利用 v-if 指令来判断当前用户是否有访问该组件的权限,并根据权限设置组件的显示和隐藏。

<template> 
    <el-button type="success" plain v-permission="'sys:user:add'">添加用户1</el-button>
</template> 

<script setup> 
import { userPermissionsStore } from '@/store/index'
import { storeToRefs } from 'pinia'
const store = userPermissionsStore()
const { userPermissions } = storeToRefs(store)

const vPermission = {
  mounted(el, binding) {
    const requiredPermission = binding.value;
    if (!userPermissions.value.includes(requiredPermission)) {
      el.style.display = 'none';
    }
  }
} 
</script>
2、使用方法控制
<template> 
     <el-button type="primary" plain v-if="hasPermission('sys:user:add')">添加用户1</el-button>
</template> 

<script setup> 
import { userPermissionsStore } from '@/store/index'
import { storeToRefs } from 'pinia'
const store = userPermissionsStore()
const { userPermissions } = storeToRefs(store)

const hasPermission = (permission) => {
  return userPermissions.value.includes(permission);
}
</script>
3、封装一个权限控制组件来实现组件层面控制权限
3.1、组件页面 Authority.vue
<template>
    <slot v-if="showSlot" :userPermissions="userPermissions"></slot>
</template>

<script setup>
import { computed } from 'vue';

import { storeToRefs } from 'pinia'
import { userPermissionsStore } from '@/store/index'
const store = userPermissionsStore()
// 为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()
const { userPermissions } = storeToRefs(store)

const props = defineProps({
	// 需要的权限
    permissions: {
        type: [String, Array]
    }
});

const showSlot = computed(() => {
    if (!props.permissions) {
        return true
    }
    if (!userPermissions.value) {
        return false
    }
    if (Array.isArray(props.permissions)) {
        return props.permissions.every(p => {
            return userPermissions.value.includes(p)
        })
    } else {
        return userPermissions.value.includes(props.permissions)
    }
})

</script>

<style scoped>
</style>
3.2、使用页面 app.vue
<template>
  <el-select v-model="value" placeholder="请选择" @change="change" style="width: 300px; margin: 20px 0;">
    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
  </el-select>

  <div>
    <!-- 这里可以根据返回的权限,做自己想判断的事情 -->
    <Authority>
      <template #default="{ userPermissions }">
        <el-button :disabled="!userPermissions.includes('sys:user:delete')" type="primary">禁用用户1</el-button>
      </template>
    </Authority>
    <!-- 传入组件所需要的权限 -->
    <Authority permissions="sys:user:view">
      <el-button>查询用户2</el-button>
    </Authority>
    <Authority permissions="sys:user:update">
      <el-button type="success">修改用户3</el-button>
    </Authority>
    <Authority permissions="sys:user:delete">
      <el-button type="info">删除用户4</el-button>
    </Authority>
    <Authority permissions="sys:user:add">
      <el-button type="warning">添加用户5</el-button>
    </Authority>
    <Authority :permissions="['sys:user:update', 'sys:user:delete']">
      <el-button type="danger">禁用用户6</el-button>
    </Authority>
  </div>
</template>

<script setup>
import Authority from '@/components/Authority.vue'
import { ref } from 'vue'

const value = ref('')
const options = [{
  value: '0',
  label: 'admin',
  permissions: ["sys:user:view", "sys:user:update", "sys:user:delete", "sys:user:add"]
}, {
  value: '1',
  label: 'editor',
  permissions: ["sys:user:view", "sys:user:update", "sys:user:add"]
}, {
  value: '2',
  label: 'guest',
  permissions: ["sys:user:view"]
}]

import { userPermissionsStore } from '@/store/index'
const store = userPermissionsStore()
// 作为 action 的 setUserPermissions 可以直接解构
const { setUserPermissions } = store
const change = (e) => {
  setUserPermissions(options[e].permissions)
}

</script>

<style scoped>
</style>
3.3、效果预览

这里使用el-select下拉框切换用户角色,存储pinia,是为了演示不同用户,不同的角色权限切换效果。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/395079.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

曲线生成 | 图解B样条曲线生成原理(基本概念与节点生成算法)

目录 0 专栏介绍1 什么是B样条曲线&#xff1f;2 基函数的de Boor递推式3 B样条曲线基本概念图解4 节点生成公式 0 专栏介绍 &#x1f525;附C/Python/Matlab全套代码&#x1f525;课程设计、毕业设计、创新竞赛必备&#xff01;详细介绍全局规划(图搜索、采样法、智能算法等)…

AIGC ChatGPT4完成业务需求SQL学习

源表如下&#xff1a; 例如现在需要显示每个岗位中工资排名前10位的员工信息&#xff0c;并显示排名应该要怎么做呢&#xff1f; Prompt: 有一个某公司职员表&#xff0c;表名为Bank_emp&#xff0c;empno为员工编号&#xff0c;ename为员工姓名&#xff0c;JOB为员工岗位&…

Codeforces Round 924 (Div. 2)题解(A-D)

A - Rectangle Cutting 链接&#xff1a;A - Rectangle Cutting 思路 考虑横边和纵边&#xff0c;若为偶数&#xff0c;则从中间分开&#xff0c;重新组合为一个长方形&#xff0c;检测是否与原来的长方形一致。 代码 #include <bits/stdc.h> using namespace std;i…

H62410Y 100V高压DCDC降压恒压芯片 可用于仪表仪器供电方案

H62410Y是一种内置100V耐压MOS&#xff0c;支持输入高达90V的高压降压开关控制器&#xff0c;可以向负载提供0.5A的连续电流。H62410Y支持输出恒定电压&#xff0c;可以通过调节VFB采样电阻来设置输出电压&#xff0c;同时支持最大电流限制&#xff0c;可以通过修改CS采样电阻来…

KMS密钥管理有哪些安全功能

KMS(Key Management Service)密钥管理服务是一种专门用于管理和保护加密密钥的系统。在现代的信息安全领域中&#xff0c;密钥的重要性不言而喻&#xff0c;它是确保数据加密、解密以及身份验证等安全操作的核心要素。KMS的出现&#xff0c;极大地提高了密钥管理的效率和安全性…

羊大师的羊奶有几种口味呢?

羊大师提供的羊奶有6种不同口味可供选择。 1.新鲜羊奶不仅没有膻味&#xff0c;而且富含高钙无糖&#xff0c;并且含有丰富的优质蛋白质和超过200种营养物质。这非常适合缺钙或体弱的人饮用。 2.益生菌羊奶是一种含有保加利亚乳杆菌、嗜酸乳杆菌、双歧杆菌等益生菌群的产品&…

无水印视频下载怎么做?这三个方法轻松搞定

在互联网时代&#xff0c;视频已成为我们获取信息、娱乐休闲的重要媒介。然而&#xff0c;有时我们可能会遇到网络不佳、时间限制或设备限制等情况&#xff0c;导致无法在线流畅观看视频。这时&#xff0c;视频下载工具就显得尤为重要。它们能够帮助我们轻松下载在线视频&#…

(个人学习之计算机网络知识总结)

备注:本人写这个计算机网络的知识点只是用于个人学习。 TCP/IP协议 从字面意义上讲&#xff0c;有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议。实际生活当中有时也确实就是指这两种协议。然而在很多情况下&#xff0c;它只是利用 IP 进行通信时所必须用到的协议群的统称。…

HTTP基本概念-HTTP 常见的状态码有哪些?

资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) HTTP 常见的状态码有哪些? 1xx 类状态码属于提示信息&#xff0c;是协议处理中的一种中间状态&#xff0c;实际用到的比较少。 2xx 类状态码表示服务器成功处理了客户端的请求&#xff0c;也是我们最愿…

netfilter

netfilter 是 linux 网络系统中的一个子系统&#xff0c;从名字也能看出来 netfilter 的作用&#xff1a;网络过滤&#xff0c;linux 内核中网络报文的处理会经历多个协议层&#xff0c;多个环节。netfilter 即在报文处理路径上加上检查点&#xff0c;每个检查点都可以设置一些…

【算法】基础算法002之滑动窗口(二)

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 5.水果成篮&#xff…

c++入门学习⑥——友元和运算符重载

目录 简介&#xff1a; 友元&#xff1a; 全局函数做友元 类做友元 成员函数做友元 运算符重载 加号运算符重载 代码示例&#xff1a; 输入输出运算符重载 ⭐cin ⭐cout 代码示例&#xff1a; 分析&#xff1a; 自增运算符重载 代码示例&#xff08;成员函数实现…

Paper - CombFold: Predicting structures of large protein assemblies 推理流程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/136165853 CombFold 是一种新的组装技术&#xff0c;可以利用 AlphaFold-Multimer 预测的可能的亚复合物的结构&#xff0c;来构建大型蛋白质复合…

【Oracle】玩转Oracle数据库(二):体系结构、存储结构与各类参数

前言 嘿伙计们&#xff01;准备好了吗&#xff1f;今天我要和你们探讨一个酷炫的话题——Oracle数据库&#xff01;&#x1f389; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;二&#xff09;&#xff1a;体系结构、存储结构与各类参数&#xff0c;我们要揭开Oracle数据库…

甲方紧急需求带来封闭式开发,项目负责人如何做好团队共识?

在职场上总会遇到各种类型的甲方金主&#xff0c;项目开展过程中也难免出现多种变更要求。本期小编就结合一位希赛学员的工作经验分享&#xff0c;一起来大家探讨下&#xff1a;面对甲方的紧急需求&#xff0c;项目经理该如何做才能带领团队克服困难&#xff0c;最终促成项目收…

【Prometheus】node-exporter、server、Grafana安装与配置

基于Prometheus和K8S构建智能化告警系统 一、Prometheus对kubernetes的监控二、node-exporter组件安装和配置2.1、node-exporter介绍2.2、安装node-exporter【1】拉取镜像【2】编写yaml文件【3】运行pod【4】获取数据 三、Prometheus server安装和配置3.1、创建sa账号&#xff…

Mysql 权限与安全管理

0 引言 MySQL是一个多用户数据库&#xff0c;具有功能强大的访问控制系统&#xff0c;可以为不同用户指定允许的权限。MySQL用户可以分为普通用户和root用户。root用户是超级管理员&#xff0c;拥有所有权限&#xff0c;包括创建用户、删除用户和修改用户的密码等管理权限&…

单机环境搭建Redis伪集群

1、Redis版本 [rootwsdhla ~]# redis-server -v Redis server v6.2.6 sha00000000:0 mallocjemalloc-5.1.0 bits64 buildbf23dac15dfc00fa[rootwsdhla ~]# redis-cli -v redis-cli 6.2.62、创建节点目录 创建6个节点目录&#xff0c;分别复制一份redis.conf并编辑&#xff1a…

电路设计(20)——数字电子钟的multism仿真

1.设计要求 使用数字芯片&#xff0c;设计一个电子钟&#xff0c;用数码管显示&#xff0c;可以显示星期&#xff0c;时、分、秒&#xff0c;可以有按键校准时间。有整点报警功能。 2.设计电路 设计好的multism电路图如下所示 3.芯片介绍 时基脉冲使用555芯片产生。在仿真里面…

hal/SurfaceFlinger/perfetto实战需求问题探讨作业-千里马framework开发

背景 hi&#xff0c;粉丝朋友们&#xff1a; 在新课halperfettosurfaceflinger https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg 推出后&#xff0c;各位学员朋友们都积极响应&#xff0c;开始马不停蹄的学习&#xff0c;学员学习后希望有更多的实战案例或者项目拿来练手&…