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,是为了演示不同用户,不同的角色权限切换效果。

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

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux命令记不住?保姆级教程来了

在软件开发过程中&#xff0c;Linux操作系统因其稳定性、安全性和高效性而备受青睐。作为开发者&#xff0c;熟练掌握Linux常用命令&#xff0c;不仅可以提高工作效率&#xff0c;还能更好地管理服务器和进行代码部署。本文将介绍一些开发常用的Linux命令及其应用场景&#xff…

JavaScript数组常见实例方法:forEach、filter、map、reduce、find、every等

博客背后的故事 其实我23年7月就学过这些数组方法了&#xff0c;但是为什么24年3月才做笔记呢&#xff1f;这就要讲一个小故事了&#xff08;不想听故事的同学自行拖动滚动条&#xff09; 24年年初我和两个队友合作开发一个小程序。JavaScript中数组的实例方法我已经学了很久…

Docker下Jenkins打包java项目并部署

docker 构建Jenkins sudo docker run --namezen_haslett --userjenkins --privilegedtrue --volume/home/cyf/server/jenkins/jenkins_home:/var/jenkins_home -v /usr/lib/jvm/java-17-openjdk-amd64:/usr/lib/jvm/java-17-openjdk-amd64 -v /usr/lib/maven/apache-mav…

VIM编译器的安装

文章目录 前言一、VIM软件安装二、遇到问题三、VIM使用1.文档创建命令touch2.VIM编译器输入模式3.VIM编译器指令模式3.VIM编译器底行模式4.VIM编译器使用小技巧 前言 &#x1f4a6; 我们如果要在终端模式下进行文本编辑或者修改文件就可以使用 VIM 编辑器&#xff0c;VIM 编辑…

treeview控件的应用

1.分类 treeview控件的基本应用&#xff0c;可以用于商品分类、文件分类等等。 2.辅助决策 treeview可以组成决策树&#xff0c;用来帮助人们做选择。比如说今天中午吃什么菜&#xff1f; 如果我来选择的话&#xff0c;那就是&#xff1a;不吃辣-鲁菜-糖醋鲤鱼。 3.求解算…

AD1102 小封装的3.7V锂电池转干电池使用的充放电管理芯片 替代传统干电池、镍氢电池

AD1102是一款锂电池充放电管理专用芯片。充电工作时&#xff0c;可以为 3.7V锂电池进行充电&#xff0c;电流最高可配置 1A。放电工作时&#xff0c;采用开关频率1MHz同步降压转换器进行放电&#xff0c;放电电流可以达到 3A。内部集成欠压保护、短路保护、过温保 护功能。 …

二 centos 7.9 磁盘挂载

上一步 一 windso10 笔记本刷linux cent os7.9系统-CSDN博客 笔记本有两个盘,系统装在128G的系统盘上,现在把另外一个盘挂载出来使用 lsblk 发现磁盘已经分好了,直接挂载就好了,参考文章:Centos7.9 挂载硬盘_centos7.9挂载硬盘-CSDN博客 永久挂载 lsblk -f分区格式化 mkfs…

XUbuntu22.04之reboot关机无效, 定制重启和关机(二百二十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

2024届 C++ 刷题 笔试强训 Day 01

选择题 01 以下for循环的执行次数是&#xff08;&#xff09; for(int x 0, y 0; (y 123) && (x < 4); x); A 是无限循环 B 循环次数不定 C 4次 D 3次 解题思路&#xff1a; 我们直接来看本道题中最关键的部分&#xff1a;(y 123) && (x < 4)。 (y…

漏洞挖掘 | 公益SRC上榜技巧

目录 1、寻找漏洞 2、挖掘漏洞 3、提交报告 4、上榜吉时 5、快速上分 6、小技巧&#xff1a;冲榜拿分制胜点-拉开人与人之间的差距 1、寻找漏洞 寻找漏洞的2种办法&#xff1a; 1)谷歌语法 注意&#xff1a;用谷歌语法找站的时候&#xff0c;要加点中文&#xff0c;不然搜…

STL之set容器代码详解

1 基础概念 所有元素都会在插入时自动被排序 本质&#xff1a; set/multiset属于关联式容器&#xff0c;底层结构是用二叉树实现。 set和multiset区别&#xff1a; set不允许容器中有重复的元素&#xff1b; multiset允许容器中有重复的元素 。 2 代码示例 Talk is chea…

Graphpad Prism10.2.1(395) 安装教程 (含Win/Mac版)

GraphPad Prism GraphPad Prism是一款非常专业强大的科研医学生物数据处理绘图软件&#xff0c;它可以将科学图形、综合曲线拟合&#xff08;非线性回归&#xff09;、可理解的统计数据、数据组织结合在一起&#xff0c;除了最基本的数据统计分析外&#xff0c;还能自动生成统…

基于51单片机 模拟简易自动自助售货机设计 智能售卖机系统

1、本设计基于STC89C51/52&#xff08;与AT89S51/52、AT89C51/52通用&#xff0c;可任选&#xff09;&#xff0c;拍的时候要备注&#xff0c;不备注默认发STC89C52RC2、使用单片机设计&#xff0c;设有8个按键&#xff0c;3个硬币模拟按键&#xff08;5元、1元、5角&#xff0…

Day31-计算机基础1

Day31-计算机基础1 1. 网络基础介绍1.1 什么是网络&#xff1f;1.2 为什么要有网络&#xff1f;1.3 运维人员需要学习哪些网络知识&#xff1f;1.4 按作用范围对网络分类 2.网络设备知识2.1 网络传输介质及传输信号2.2 网卡设备2.3 中继器&#xff08;RP repeater&#xff09;2…

JavaScript 实现飞机大战

文章目录 一些关键点概览&#xff1a;核心模块的具体实现示例&#xff1a;飞机类&#xff08;Plane&#xff09;的基本结构&#xff1a;子弹类&#xff08;Bullet&#xff09;的基本结构&#xff1a;敌机类&#xff08;Enemy&#xff09;的基本结构&#xff1a; 基于前面定义的…

SQL盲注-实战布尔盲注

环境&#xff1a;win10 靶场&#xff1a;sqli-labs-master 本实验仅供学习参考&#xff01;&#xff01;&#xff01; 1 布尔盲注 盲注就是在 SQL 注入过程中&#xff0c; SQL 语句执行后&#xff0c;查询到的数据不能 回显到前端页面。此时&#xff0c;我们需要利用一些方…

滤波器:工作原理和分类及应用领域?|深圳比创达电子EMC

滤波器在电子领域中扮演着重要的角色&#xff0c;用于处理信号、抑制噪声以及滤除干扰。本文将详细介绍滤波器的工作原理、分类以及在各个应用领域中的具体应用。 一、滤波器的定义和作用 滤波器是一种电子设备&#xff0c;用于选择性地通过或阻塞特定频率范围内的信号。其主…

iOS增量报告生成方案

一&#xff0c;iOS覆盖率报告生成逻辑 iOS覆盖率报告生成与Android有很大的不同&#xff0c;主要的生成逻辑如下&#xff1a; 1&#xff0c;将profraw文件&#xff0c;通过命令xcrun llvm-profdata merge -sparse转换成profdata; 2&#xff0c;再将profdata文件&#xff0c;通…

牛客论坛笔记~

文章目录 Redisspring整合redis实现点赞帖子的赞用户的赞 关注功能热帖排行redis存储验证码、登录凭证、用户信息 kafka阻塞队列kafka![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d35be55986344b548710985cd8ecbd87.png)触发事件处理事件 Redis高级网站数据统计…

如何使用 ArcGIS Pro 制作三维地形图

伴随硬件性能的提高和软件算法的优化&#xff0c;三维地图的应用场景会越来越多&#xff0c;这里为大家介绍一下在ArcGIS Pro怎么制作三维地形图&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的DEM和影像数据&#xff0c;除了DEM和影像数据…