2.2 iHRM人力资源 - 主页权限认证、Vux共享用户资料

iHRM人力资源 - 主页权限认证、主页内容展示

2.IHRM人力资源 - 登录-CSDN博客

文章目录

  • iHRM人力资源 - 主页权限认证、主页内容展示
  • 一、主页权限认证
    • 1.1 主页权限认证分析
    • 1.2 主页权限认证 - permission.js
      • 1.2.1 进度条部分
      • 1.2.2 token 认证
  • 二、Vuex共享用户资料
    • 2.1 需求分析
    • 2.2 路由前置守卫 实现共享用户资料
      • 2.2.1 vuex - user.js
      • 2.2.2 vuex - getters.js
      • 2.2.3 api - getUserInfo
      • 2.2.4 permission.js 前置路由器
      • 2.2.5 测试
    • 2.3 显示用户名称及头像
      • 2.3.1 getters.js暴露用户名称与头像
      • 2.3.2 Navbar.vue 顶部组件
      • 2.3.3 最终效果图
    • 2.4 处理用户头像为空场景

一、主页权限认证

1.1 主页权限认证分析

主页权限认证其实就是验证有没有token

token所在位置

image-20240115190158125

访问主页时

  • 有token

    放过请求,可以跳转到主页

  • 无token

    拦截访问主页的请求并跳转到登录页让用户进行登录

访问登录页时

  • 有token

    直接跳转到主页

  • 无token

    正常访问登录页面

我们可以看一下下面permission.js代码

image-20240115190355269

将代码收起来看很简洁,一个前置路由守卫beforeEach,一个后置路由守卫router.afterEach

Vue - 路由守卫

image-20240115190439134

然后再main.js文件中将路由守卫配置引入

image-20240115190625980

1.2 主页权限认证 - permission.js

主页权限验证就参考下图来就可以

image-20240115191124459

1.2.1 进度条部分

如下所示是一个进度条的插件,要想使用这个插件,直接引入到我们package.json文件中即可

image-20240115212452236

进度条的效果如下所示

image-20240115212853073

// 导入路由实例
import router from '@/router'
// 引入进度条
import nprogress from 'nprogress'
// 引入进度条对应的样式
import 'nprogress/nprogress.css'
// 引入vuex实例对象
import store from '@/store'/*** 前置守卫* 参数:*  to:信息要到哪里去*  from:信息从哪里来*  next:必须要执行的函数。如果不执行next,跳转就不会执行。说白了就是让着通行,如果没有next的话,页面会直接空白*/
router.beforeEach((to, from, next) => {// 前置守卫开启进度条nprogress.start()next()
})/*** 后置守卫*/
router.afterEach(() => {// 关闭进度条 nprogress.done()
})

1.2.2 token 认证

// 导入路由实例
import router from '@/router'
// 引入进度条
import nprogress from 'nprogress'
// 引入进度条对应的样式
import 'nprogress/nprogress.css'
// 引入vuex实例对象
import store from '@/store'// 定义白名单,此路径不需要token就可以访问
const whiteList = ['/login', '/404']
/*** 前置守卫* 参数:*  to:信息要到哪里去*  from:信息从哪里来*  next:必须要执行的函数。如果不执行next,跳转就不会执行。说白了就是让着通行,如果没有next的话,页面会直接空白*/
router.beforeEach((to, from, next) => {// 前置守卫开启进度条nprogress.start()if (store.getters.token) {// 存在token// 判断要去的地方是不是登录页面if (to.path === '/login') {// 此时已经登录了,那就直接跳转到主页而不是登录页// next("/") 表示中转页面到主页next('/')// 当next(地址)时并没有执行后置路由守卫,所以说也不会再后置守卫中关闭进度条了nprogress.done()} else {// 说明访问的不是登录页,直接放过就好了next()}} else {//   没有token// 首先先验证白名单中是否包含路径to.path 使用whiteList.indexOf(to.path) > -1判断也可以if (whiteList.includes(to.path)) {// 直接放行next()} else {// 中转到登录页next('/login')// 手动关闭进度条nprogress.done()}}
})/*** 后置守卫*/
router.afterEach(() => {nprogress.done()
})

二、Vuex共享用户资料

我们要获取用户的资料并使用Vuex实现用户资料的共享

2.1 需求分析

我们登录之后要获取用户的资料,比如说用户名、用户头像,然后把用户资料放在Vuex中进行共享

流程分析

  • 登录之后获取当前用户的资料

    其实就是有了token之后我们才能知道是谁来获取用户的资料

  • 把获取的用户资料在Vuex中共享

流程图如下所示

image-20240116104515358

假如我们把获取用户资料的代码写在"Dashboard"模块,那首先访问Dashboard也就是主页的时候我们完全可以调用请求/sys/profile得到用户信息的资料,然后放在Vuex中做成数据共享

但是假如用户首先访问的不是Dashboard主页模块,而是“Example”或其他模块的话,就不会调用请求/sys/profile得到用户信息的资料,然后放在Vuex中做成数据共享

所以我们在哪里实现请求/sys/profile获取数据再把数据放在Vuex中显得非常的重要

image-20240119164545073

我们在哪个位置能保证让所有的模块都能调用咱的action方法实现用户资料共享呢

也就是说不管我们切换到哪个页面,我们都能拿到用户共享资料

路由前置守卫,我们在这里编写,只要切换页面就会执行,而且也会判断是否有token

假如说我们的Vuex中有用户资料信息,就不要再重复进行获取了,我们只保证没有用户资料信息的时候进行获取

image-20240119165905283

2.2 路由前置守卫 实现共享用户资料

我们可以在“src/permission.js”中的前置守卫进行实现

image-20240119171434173

2.2.1 vuex - user.js

我们在vuex中的用户模块user.js中获取用户资料信息,并存储在vuex中

image-20240119175900805

// @符号表示根路径
import { getToken, setToken, removeToken } from '@/utils/auth'
import { login, getUserInfo } from '@/api/user'
// State理解为数据源,像极了我们之前学的data,用来存放数据
const state = {// 存储用户基本资料状态userInfo: {}.......
}/*** actions似java中的业务逻辑层,对逻辑操作,然后向mutations发送数据,在这个业务逻辑中也可以互相调用* actions可以做异步操作*/
const actions = {// 获取用户基本资料async getUserInfo(context) {// 获取用户基本资料const result = await getUserInfo()context.commit('setUserInfo', result)}......................
}

2.2.2 vuex - getters.js

我们可以通过userId判断是否已经获取了用户资料信息,如果userId存在数据说明已经获取了,之后就不要再获取了

image-20240119175355240

const getters = {sidebar: state => state.app.sidebar,device: state => state.app.device,token: state => state.user.token,// vuex中user模块的userInfo里面的userIduserId: state => state.user.userInfo.userId,avatar: state => state.user.avatar,name: state => state.user.name
}
export default getters

2.2.3 api - getUserInfo

image-20240119161023537

// 获取用户基本信息
export function getUserInfo() {return request({// 请求地址url: '/sys/profile',// 请求方式method: 'GET'// 请求参数// data: Data})
}

2.2.4 permission.js 前置路由器

在此模块的前置路由中编写,逻辑的主要实现会在这里

image-20240119171434173

// @符号表示根路径
import { getToken, setToken, removeToken } from '@/utils/auth'
import { login, getUserInfo } from '@/api/user'
// State理解为数据源,像极了我们之前学的data,用来存放数据
const state = {// 这样就算我们给state.token赋值之后,但刷新页面后仍然是null,所以此时永远不能取到我们缓存的token值// token: null// 从缓存中读取初始值token: getToken(),// 存储用户基本资料状态userInfo: {}
}// Mutations类似java中的数据层,只对数据进行操作,不对业务操作(比如数据加减乘除)
const mutations = {// 修改tokensetToken(state, token) {state.token = token// console.log(state.token)// 将token值同步到缓存setToken(token)},removeToken() {// 删除vuex的tokenstate.token = null// 删除缓存中的tokenremoveToken()},setUserInfo(state, userInfo) {state.userInfo = userInfo}
}/*** actions似java中的业务逻辑层,对逻辑操作,然后向mutations发送数据,在这个业务逻辑中也可以互相调用* actions可以做异步操作*/
const actions = {/*** 参数1: context上下文对象,有commit和dispatch方法* 参数2:我们要传入的参数*/async login(context, data) {// 只有后台返回的success的值为true时才走await,如果是false的话就走了axios响应拦截器中的reject,就不会向下走了const token = await login(data)// 假设登录成功之后就会返回一个token,我们要将此token实现共享就要存储在state中// vuex中想修改state中数据必须通过mutations,不能直接修改state中属性// 运行到这里说明登录已经成功了context.commit('setToken', token)},// 获取用户基本资料async getUserInfo(context) {console.log('打印用户基本信息')// 获取用户基本资料const result = await getUserInfo()console.log(result)context.commit('setUserInfo', result)}
}// 对三个变量进行一个默认的导出
export default {// 开启命名空间。表示之后调用state/mutations/actions时必须带上模块名称namespaced: true,state,mutations,actions
}

其实这个地方我们只写了这一点代码而已,其他的都是之前写过的

image-20240119180647710

2.2.5 测试

随便打开一个页面刷新测试即可,如果有信息说明哪个界面都能获取到用户基本信息,我们做的就是对对对对对对的!!!

image-20240119180915485

2.3 显示用户名称及头像

将Vuex中共享的用户信息显示在顶部组件上

image-20240122152228661

顶部组件也就是下面标红的“navbar”

image-20240122152359457

2.3.1 getters.js暴露用户名称与头像

我们的用户资料信息都存储在vuex中的user.js模块

image-20240122155058524

接下来使用getters便捷访问用户的名称和头像

const getters = {sidebar: state => state.app.sidebar,device: state => state.app.device,token: state => state.user.token,// vuex中user模块的userInfo里面的userIduserId: state => state.user.userInfo.userId,avatar: state => state.user.userInfo.staffPhoto, // 用户头像name: state => state.user.userInfo.username // 用户名称
}
export default getters

2.3.2 Navbar.vue 顶部组件

image-20240122155750257

  <div class="navbar"><hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar"/><breadcrumb class="breadcrumb-container"/><div class="right-menu"><el-dropdown class="avatar-container" trigger="click"><div class="avatar-wrapper"><!--用户头像--><img :src="avatar" class="user-avatar"><!--用户名称--><span class="name">{{ name }}</span><!--图标(设置图标,是一个齿轮的样式)--><i class="el-icon-setting"/></div><el-dropdown-menu slot="dropdown" class="user-dropdown">..................</el-dropdown-menu></el-dropdown></div></div>
</template>

Navbar组件引入用户名与用户头像

computed: {// 辅助函数,自动引入getters中的属性// 引入头像和用户名称...mapGetters(['sidebar','avatar','name'])
}

样式

.navbar {.right-menu {.avatar-container {margin-right: 30px;.avatar-wrapper {margin-top: 5px;position: relative;// 水平居中display: flex;align-items: center;// 用户名样式.name {// 用户名称距离右侧一定的距离margin-right: 10px;// 文字大小font-size: 16px;}// 用户头像样式.user-avatar {cursor: pointer;width: 30px;height: 30px;// 设置圆角border-radius: 50%;}// 齿轮图标样式.el-icon-setting {font-size: 20px;}.el-icon-caret-bottom {cursor: pointer;position: absolute;right: -20px;top: 25px;font-size: 12px;}}}}
}

2.3.3 最终效果图

image-20240122163628153

2.4 处理用户头像为空场景

当用户没有自己设置用户名时,用户的头像就显示用户名的第一个字

image-20240122164012364

首先升级一下vue版本,目的是我们想要支持可选操作符的语法

npm i vue@2.7.0 vue-template-compiler@2.7.0
  <div class="navbar"><hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar"/><breadcrumb class="breadcrumb-container"/><div class="right-menu"><el-dropdown class="avatar-container" trigger="click"><div class="avatar-wrapper"><!--如果用户头像不存在的时候执行下面的v-else,显示用户名的第一个字--><!--当name时null或者undefined时name.charAt(0)会报错,但是当在name之后加上“?”后,如果name为null或者undefined,就不会执行charAt(0),也不会报错了--><!-- "name?" 可选操作符,表示验证name是否一定有值。 此语法需要vue2.7.0之后的版本--><span v-else class="username">{{ name?.charAt(0) }}</span><!--如果用户头像不存在的时候执行下面的v-else,显示用户名的第一个字--><span v-else class="username">{{name.charAt(0)}}</span><!--用户名称--><span class="name">{{ name }}</span><!--图标(设置图标,是一个齿轮的样式)--><i class="el-icon-setting"/></div><el-dropdown-menu slot="dropdown" class="user-dropdown">..................</el-dropdown-menu></el-dropdown></div></div>
</template>

对应的样式

.navbar {.right-menu {.avatar-container {margin-right: 30px;.avatar-wrapper {margin-top: 5px;position: relative;// 水平居中display: flex;align-items: center;// 用户头像不存在时,默认使用使用用户名的第一个字当做头像.username {// 垂直居中width: 30px;height: 30px;line-height: 30px;// 水平居中text-align: center;// 背景颜色background-color: #04c9be;// 字体颜色color: #fff;// 圆角border-radius: 50%;// 距离右边距margin-right: 4px;}}}}
}

效果图

image-20240122225003642

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

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

相关文章

深入理解大语言模型微调技术

一、概念解析 1、什么是微调&#xff08;Fine-tuning&#xff09;&#xff1f; 大模型微调&#xff0c;也称为Fine-tuning&#xff0c;是指在已经预训练好的大型语言模型基础上&#xff08;一般称为“基座模型”&#xff09;&#xff0c;使用特定的数据集进行进一步的训练&am…

【Delphi 爬虫库 1】GET和POST方法

文章目录 1.最简单的Get方法实现2.可自定义请求头、自定义Cookie的Get方法实现3.提取响应协议头4.Post方法实现单词翻译 爬虫的基本原理是根据需求获取信息并返回。就像当我们感到饥饿时&#xff0c;可以选择自己烹饪食物、外出就餐&#xff0c;或者订外卖一样。在编程中&#…

ROS 2边学边练(26)-- 监测参数变化(C++)

前言 通常&#xff0c;一个节点需要对其自身参数或另一个节点的参数的更改做出响应。ParameterEventHandler类使监听参数更改变得容易&#xff0c;这样代码就可以对它们做出响应。 动动手 创建一个包 进入工作空间根路径的src下&#xff08;ros2_ws/src&#xff09;&#xff…

基于区块链Hyperledger FabricV2.5的农产品溯源/商品/通用溯源应用系统模板

本项目所有相关文档包括区块链设计、后端设计、前端设计、结合IPFS改进以及简易的二次开发步骤收录于&#xff1a;《Fabric项目学习笔记》&#xff0c;当前本项目文档已全部发布。 购买专栏前请认真阅读&#xff1a;《Fabric项目学习笔记》专栏介绍 本项目的代码讲解与二次开发…

Unity 左右折叠显示与隐藏UI的简单实现

要实现一个简单的UI左右折叠显示与隐藏&#xff0c;可以结合遮罩&#xff0c;通过代码控制UI区块的宽度和位移来实现。 具体可以按以下步骤实现&#xff1a; 1、新建一个Image组件&#xff0c;并添加精灵&#xff0c;调整大小后&#xff0c;复制一份作为该UI的父物体&#xf…

光纤不够用怎么办?使用DWDM波分进行低成本扩容光纤容量

光通信行业一直有CWDM/DWDM/LWDM&#xff0c;波分复用&#xff08;WDM&#xff09;是一种光纤传输技术&#xff0c;可以使用多种光波长&#xff08;或颜色&#xff09;在同一介质上发送数据。两个或多个波长可以在一根光纤上传播&#xff0c;并且可以在光波导中以不同的波长或光…

阿赵UE学习笔记——28、粒子系统Niagara简介

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的使用。这次开始学习粒子系统的使用。 一、Cascade系统 在介绍UE5的Niagara系统之前&#xff0c;必须先介绍一下旧版本的粒子系统。   在UE4的时候&#xff0c;虚幻引擎的粒子系统叫做Cascade&#x…

大数据平台搭建2024(一)

一&#xff1a;基础配置 创建虚拟机并查出ip地址进行连接 ip a1.配置node01静态ip地址与主机名 vi /etc/sysconfig/network-scripts/ifcfg-ens33修改或添加如下内容&#xff1a; BOOTPROTO"static" ONBOOTyes #根据虚拟机网卡信息配置 IPADDR192.168.200.141 NET…

Sonatype Nexus 的使用参数

在最近安装的 Sonatype Nexus 版本中提供了一个使用参数情况界面。 这个使用情况的界面主要是针对当前 Sonatype Nexus 的安装实例出现的系统接入和调用情况。 上面提供了一个限制&#xff0c;这个限制不是说达到了限制后拒绝提供服务了&#xff0c;而是因为在默认的 Sonatype…

强化学习(三)基于动态规划 Dynamic Programming 的求解方法

文章目录 1. 动态规划与强化学习的联系2. 利用动态规划求解最优价值函数2.1 案例背景2.2 策略评估&#xff08;预测&#xff09;2.3 策略迭代&#xff08;控制&#xff09; 在前文《强化学习的数学框架&#xff1a;马尔科夫决策过程 MDP》中&#xff0c;我们用马尔可夫过程抽象…

Android JetPack Compose+Room----实现搜索记录功能

文章目录 需求概述功能展示实现搜索功能使用的技术1.Android Jetpack room2.Android JetPack Compose 代码实现编写搜索界面接入Room实现搜索功能的管理引入依赖定义包结构定义操作表的Dao类定义数据库的基础配置定义数据库的Dao管理类使用数据库升级 源码地址 需求概述 搜索功…

Mac搭建Java环境【环境搭建】

Mac搭建Java环境【环境搭建】 1 安装Java SDK 官网地址&#xff1a;https://www.oracle.com/java/technologies/downloads/archive/ 下载dmg&#xff0c;双击之后无脑安装即可。 # 进入 JDK 安装目录 cd /Library/Java/JavaVirtualMachines# 查看文件 ls# 输入 cd ~# 打开环…