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.rhkb.cn/news/311566.html

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

相关文章

day02|最小花费爬梯子

最小花费爬梯子 比如 有一个数组 【2 5 20】我们直接选择从1号梯子&#xff08;从零编号&#xff09;跳两格就出去了。 算法原理 我们可以得出楼顶其实是数组的最后一个元素的下一个位置。对于最值问题我们可以尝试使用dpdp我们首先应该定义状态方差的含义&#xff0c;一般以…

Linux的重要命令(二)+了解Linux目录结构

目录 一.Linux的目录结构 二.查看文件内容命令 1.cat 命令 2.more 命令 3.less 命令 4.head 命令 5.tail 命令 6.拓展 head 和 tail 的其他用法 ​编辑 三.统计文件内容的命令-wc ​编辑 四.检索和过滤文件内容的命令-grep ​编辑 ​编辑 五.压缩命令 gzip 和 bz…

android studio 网络请求okhttp3、okgo

一、在build.gradle文件里添加 implementation com.squareup.okhttp3:okhttp:4.9.0 implementation com.squareup.okhttp3:okhttp:3.12.0 implementation com.squareup.okio:okio:1.17.4 implementation com.lzy.net:okgo:3.0.4 implementation com.alibaba:fastjson:1.2.57 i…

windows下已经创建好了虚拟环境,但是切换不了的解决方法

用得多Ubuntu&#xff0c;今天用Windows重新更新anaconda出问题&#xff0c;重新安装之后&#xff0c;打开pycharm发现打开终端之后&#xff0c;刚开始是ps的状态&#xff0c;后面试了网上改cmd的方法&#xff0c;终端变成c盘开头了 切换到虚拟环境如下&#xff1a;目前的shell…

实现iOS App代码混淆

简介 在开发iOS应用程序时&#xff0c;保护代码安全是至关重要的。代码混淆是一种常用的技术&#xff0c;可以增加逆向工程的难度&#xff0c;防止他人对代码的篡改和盗用。本文将介绍如何实现iOS App代码混淆的步骤和操作方法。 整体流程 下面是实现iOS App代码混淆的整体流…

大数据平台搭建2024(一)

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

时隔一年,再次讨论下AutoGPT-安装篇

AutoGPT是23年3月份推出的&#xff0c;距今已经1年多的时间了。刚推出时&#xff0c;我们还只能通过命令行使用AutoGPT的能力&#xff0c;但现在&#xff0c;我们不仅可以基于AutoGPT创建自己的Agent&#xff0c;我们还可以通过Web页面与我们创建的Agent进行聊天。这次的AutoGP…

conda新建环境报错An HTTP error occurred when trying to retrieve this URL.

conda新建环境报错如下 cat .condarc #将 .condarc文件中的内容删除&#xff0c;改成下面的内容 vi .condarc channels:- defaults show_channel_urls: true default_channels:- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main- https://mirrors.tuna.tsinghua.…

2024年认证杯SPSSPRO杯数学建模D题(第一阶段)AI绘画带来的挑战全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现&#xff1a; 2023 年开年&#xff0c;ChatGPT 作为一款聊天型 AI 工具&#xff0c;成为了超越疫情的热门词条&#xff1b;而在 AI 的另一个分支——绘图领域&#xff0c;一款名为 Midjourney&#xff08;MJ&…

【教程】cocos2dx资源加密混淆方案详解

1,加密,采用blowfish或其他 2,自定是32个字符的混淆code 3,对文件做blowfish加密,入口文件加密前将混淆code按约定格式(自定义的文件头或文件尾部)写入到文件 4,遍历资源目录,对每个文件做md5混淆,混淆原始串“相对路径”“文件名”混淆code, 文件改名并且移动到资源目录根…

【Entity Framework】你必须要了解EF中数据查询之数据加载

【Entity Framework】你必须要了解EF中数据查询之数据加载 文章目录 【Entity Framework】你必须要了解EF中数据查询之数据加载一、概述二、预先加载2.1 包含多个层级2.2 经过筛选的包含 三、显示加载3.1查询关联实体 四、延时加载4.1 不使用代理进行延迟加载 一、概述 Entity…

电脑网络一切正常但无法上网-注意检查代理

当电脑出现无法上网&#xff0c; 但是网络适配器又一切正常的时候&#xff0c; 不妨检查一下网络代理设置&#xff0c; 看是否处于开启状态。如果是开启状态&#xff0c; 关闭后再次尝试。 代理服务器自动设置成开启状态&#xff0c; 并且代理地址服务器地址设置成127.0.0.1:1…

提升测试效率都有哪些具体手段?

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

OVITO-2.9版本

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

Matlab|电价型负荷需求响应(考虑电价变化)

程序复现来源于《计及需求响应消纳风电的电-热综合能源系统经济调度 》第四章内容。 一、原理 需求响应的基本原理是需求侧根据电力市场价格和电网要求改变其负荷需求以 获取一定的利益回报。其中 PDR 可通过直观的电价变化信号引导用户调节用电方式&#xff0c; 从而达到优…

JVM结构化体系

目录 目录 1.JVM 简介 1.1. 如何理解 JVM 呢&#xff1f; 1.2. 市场主流 JVM 分析&#xff1f; 1.3. 为什么要学习 JVM&#xff1f; 1.4. 字节码底层是如何执行呢&#xff1f; 如何理解 JIT 呢&#xff1f; 为什么 JVM 中解释执行与编译执行的并存&#xff08;混合模式&…

JavaScript 高性能编程 —— 加载和运行

JavaScript 在浏览器中的性能,可认为是开发者所要面对的最重要的可用性问题。此问题因 JavaScript 的阻塞特征而复杂,也就是说,当 JavaScript 运行时其他的事情不能被浏览器处理。 事实上,大多数浏览 器使用单进程处理 UI 更新和 JavaScript 运行等多个任务,而同一时间只能…

ADB的基本语法及常用命令

学习网址 ADB命令的基本语法如下&#xff1a; adb [-d|-e|-s <serialNumber>] <command> 如果有多个设备/模拟器连接&#xff0c;则需要为命令指定目标设备。 参数及含义如下&#xff1a; 常用命令如下&#xff1a; 1. 启动ADB服务 adb start-server 2. 停止…

OpenHarmony实战开发-Worker子线程中解压文件。

介绍 本示例介绍在Worker 子线程使用ohos.zlib 提供的zlib.decompressfile接口对沙箱目录中的压缩文件进行解压操作&#xff0c;解压成功后将解压路径返回主线程&#xff0c;获取解压文件列表。 效果图预览 使用说明 1.点击解压按钮&#xff0c;解压test.zip文件&#xff0c…

Spring底层如何执行?

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Spring底层如何执行refresh()prepareRefresh() 准备刷新的工作initPropertySources() obtainFreshBeanFactory()refreshBeanFactory()AbstractRefreshableApplicati…