人力资源智能化管理项目(day03:主页模块)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/humanResourceIntelligentManagementProject

觉得有帮助的同学,可以点心心支持一下哈

主页权限验证(permission.js)

import router from '@/router'
import nprogress from 'nprogress' // 进度条
import 'nprogress/nprogress.css' // 进度条样式
import store from '@/store'
/*** 前置守卫**/
// 白名单
const whiteList = ['/login', '/404']
router.beforeEach((to, from, next) => {nprogress.start() // 开启进度条if (store.getters.token) {// 存在tokenif (to.path === '/login') {// 跳转到主页next('/') // 中转到主页// next有地址的话并没有执行后置守卫nprogress.done()} else {next() // 放过}} else {// 没有tokenif (whiteList.includes(to.path)) {next() // 放过} else {next('/login') // 中转到登录页nprogress.done()}}
})/*** 后置守卫**/
router.afterEach(() => {console.log(123)nprogress.done() // 关闭进度条
})

获取用户资料在Vuex中共享

获取资料action的调用位置

1.封装API请求

export function getUserInfo () {// request执行之后会得到promise对象(再通过使用async和await可以获取结果)return request({url: '/sys/profile',method: 'GET'})
}

2.Vuex应用

// 存放数据
const state = {token: getToken(), // 从缓存中读取初始值userInfo: {} // 存储用户基本资料状态
}setUserInfo (state, userInfo) {state.userInfo = userInfo}// 获取用户的基本资料async getUserInfo (context) {const result = await getUserInfo()context.commit('setUserInfo', result)}

3.getters声明userId

userId: state => state.user.userInfo.userId, // 取用户id,用于判断页面是否获取过资料

4.权限拦截处调用action

// 如果不是则放过// 判断是否获取过资料if (!store.getters.userId) {// 如果没有则获取资料await store.dispatch('user/getUserInfo')}next()

显示用户头像和用户名

1.Vuex使用getters暴露属性

avatar: state => state.user.userInfo.staffPhoto, // 用户头像
name: state => state.user.userInfo.username // 用户姓名

2.Navbar组件引入

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

3.Navbar设置

<!-- 用户头像 --><img :src="avatar" class="user-avatar" /><!-- 用户名称 --><span class="name">{{ name }}</span><!-- 图标 --><i class="el-icon-setting" />

4.设置样式

.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;}

处理用户头像为空的场景

实例代码

 <!-- 用户头像 -->
<img v-if="avatar" :src="avatar" class="user-avatar" />
<span v-else class="username">{{ name?.charAt(0) }}</span>.username {width: 30px;height: 30px;line-height: 30px;text-align: center;background-color: #04c9be;color: #fff;border-radius: 50%;margin-right: 4px;}npm i vue@2.7.0 vue-template-compiler@2.7.0

处理token失效

实例代码

// 判断token值是否等于401if (error.response.status === 401) {Message({ type: 'warning', message: '登录超时了' })// token超时了await store.dispatch('user/logout') // 退出登录actionrouter.push('/login') // 跳到登录页return Promise.reject(error)}// 退出登录logout (context) {// 1.删除tokencontext.commit('removeToken')// 2.删除用户信息context.commit('setUserInfo', {})}

调整下拉菜单,实现退出登录

<!-- native事件修饰符 --><!-- 注册组件的根元素的原生事件 --><el-dropdown-item @click.native="logout"><span style="display: block">退出登录</span></el-dropdown-item>async logout () {// 调用退出登录的actionawait this.$store.dispatch('user/logout')this.$router.push('/login')}

修改密码功能实现

修改密码-弹出层

<!-- prevent阻止默认事件 --><a target="_blank" @click.prevent="updatePassword"><el-dropdown-item>修改密码</el-dropdown-item></a><!-- 放置dialog --><!-- sync可以接收子组件传过来的事件和值 --><el-dialog width="500px" title="修改密码" :visible.sync="showDialog"><!-- 放置表单 --></el-dialog>showDialog: true // 控制弹层的显示和隐藏updatePassword () {this.showDialog = true // 显示弹层}

修改密码-表单结构

<!-- 放置表单 --><el-form label-width="120px"><el-form-item label="旧密码"><el-input type="password" size="small" /></el-form-item><el-form-item label="新密码"><el-input type="password" size="small" /></el-form-item><el-form-item label="重复密码"><el-input type="password" size="small" /></el-form-item><el-form-item><el-button size="mini" type="primary">确认密码</el-button><el-button size="mini">取消</el-button></el-form-item></el-form>

修改密码-表单校验

rules: {// 旧密码oldPassword: [{ required: true, message: '旧密码不能为空', trigger: 'blur' }], // 新密码newPassword: [{ required: true, message: '新密码不能为空', trigger: 'blur' },{trigger: 'blur',min: 6,max: 16,message: '新密码的长度6-16位之间'}], // 确认密码字段confirmPassword: [{ required: true, message: '重复密码不能为空', trigger: 'blur' },{trigger: 'blur',validator: (rule, value, callback) => {if (this.passForm.newPassword === value) {callback()} else {callback(new Error('重复密码和新密码输入不一致'))}}}]}

修改密码-确定和取消

btnOk () {this.$refs.passForm.validate(async isOk => {if (isOk) {// 调用接口await updatePassword(this.passForm)this.$message.success('修改密码成功')this.btnCancel()}})},btnCancel () {// 成功之后重置表单this.$refs.passForm.resetFields()// 关闭弹层this.showDialog = false}@close="btnCancel"/*** 更新密码*/
export function updatePassword (data) {return request({url: '/sys/user/updatePass',method: 'PUT',data})
}

清理组件和路由并创建项目所需组件和路由

删除多余的组件和路由

业务模块

实例代码(department)

<template><div class="container"><div class="app-container">组织架构</div></div>
</template>
<script>
export default {name: 'Department'
}
</script>import layout from '@/layout'
export default {// 路由信息path: '/department',component: layout, // 一级路由children: [{path: '', // 二级路由地址为空时 表示 /department 显示一级路由 + 二级路由component: () => import('@/views/department'),name: 'department', // 可以用来跳转 也可以标记路由meta: {// 路由元信息 存储数据的icon: 'tree', // 图标title: '组织' // 标题}}]
}import Layout from '@/layout'
import department from './modules/department'
import approval from './modules/approval'
import attendance from './modules/attendance'
import employee from './modules/employee'
import permission from './modules/permission'
import role from './modules/role'
import salary from './modules/salary'
import social from './modules/social'{path: '/',component: Layout,redirect: '/dashboard',children: [{path: 'dashboard',name: 'Dashboard',component: () => import('@/views/dashboard/index'),meta: { title: '首页', icon: 'dashboard' }}]},department,role,employee,permission,attendance,approval,salary,social,

解析左侧菜单

显示项目logo

<router-link key="collapse" class="sidebar-logo-link" to="/"><img src="@/assets/common/logo.png" class="sidebar-logo" /></router-link>& .sidebar-logo {width: 140px;vertical-align: middle;margin-right: 12px;}&.collapse {.sidebar-logo {margin-right: 0px;width: 32px;height: 32px;}}\src\settings.js
sidebarLogo: true

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Django模板(二)

标签if 标签在渲染过程中提供使用逻辑的方法,比如:if和for 标签被 {% 和 %} 包围,如下所示: 由于在模板中,没有办法通过代码缩进判断代码块,所以控制标签都需要有结束的标签 if判断标签{% if %} {% endif %} : # athlete_list 不为空 {% if athlete_list %}# 输出 ath…

Spring + Tomcat项目中nacos配置中文乱码问题解决

实际工作的时候碰到了nacos中文乱码的问题&#xff0c;一顿排查最终还是调源码解决了。下面为具体的源码流程&#xff0c;有碰到的可以参考下。 对于nacos配置来说&#xff0c;初始主要源码就在NacosConfigService类中。里面有初始化获取配置content以及设置对应监听器的操作。…

原生JS使用PrintJs进行表格打印 -- 遇到的问题总结

需求1&#xff1a;表格自动分页之后&#xff0c;表头在每一页都需要显示 html中表头增加 thead 标签 css样式新增&#xff1a; thead {display: table-header-group; /* 这个属性使thead总是在新的page-break之后重新开始 */ }需求2&#xff1a;表格自动分页之后&#xff0c;…

Springboot 整合 Elasticsearch(三):使用RestHighLevelClient操作ES ①

&#x1f4c1; 前情提要&#xff1a; Springboot 整合 Elasticsearch&#xff08;一&#xff09;&#xff1a;Linux下安装 Elasticsearch 8.x Springboot 整合 Elasticsearch&#xff08;二&#xff09;&#xff1a;使用HTTP请求来操作ES 目录 一、Springboot 整合 Elasticsea…

c++设计模式之装饰器模式

作用 为现有类增加功能 案例说明 class Car { public:virtual void show()0; };class Bmw:public Car { public:void show(){cout<<"宝马汽车>>"<<endl;} };class Audi:public Car { public:void show(){cout<<"奥迪汽车>>&q…

2023年12月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 一个非零的二进制正整数,在其末尾添加两个“0”,则该新数将是原数的?( ) A:10倍 B:2倍 C:4倍 D:8倍 答案:C 二进制进位规则是逢二进一,因此末尾添加一个0,是扩大2倍,添加两个0…

【Linux开发工具】yum命令详解

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1.概念2.yum的配置信…

Docker-Learn(二)保存、导入、使用Docker镜像

1.保存镜像 根据上一节内容&#xff0c;将创建好镜像进行保存&#xff0c;需要退出当前的已经在运行的docer命令行中断里面&#xff0c;可以通过在终端里面输入指令exit或者按下键盘上的 ctrlD建退出&#xff1a; 回到自己的终端里面&#xff0c;输入指令&#xff1a; docker…

学习VR全景拍摄,如何选择适合的VR全景设备?

随着VR全景技术的不断成熟和发展&#xff0c;VR全景已经成为摄影爱好者、地产行业、中介经纪人、广告、企业宣传等行业从业者们乐于尝试的新领域、新手段。 如何选择合适的VR全景设备成为了一个重要的问题。今天&#xff0c;和大家聊一聊&#xff0c;不同行业、人群和用途更适合…

从Unity到Three.js(安装启动)

发现在3D数字孪生或模拟仿真方向&#xff0c;越来越多的公司倾向使用Web端程序&#xff0c;目前一直都是使用的Unity进行的Web程序开发&#xff0c;但是存在不少问题&#xff0c;比如内存释放、shader差异化、UI控件不支持复制或输入中文等。虽然大多数问题都可以找到解决方案&…

Swift Combine 发布者publisher的生命周期 从入门到精通四

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三 1. 发布者和订阅者的生命周期 订阅者和发布者以明确定义的顺序进行通信&#xff0c;因此使得它们具有从开始到结束的生命周期&#xff1a; …

Leetcode3020. 子集中元素的最大数量

Every day a Leetcode 题目来源&#xff1a;3020. 子集中元素的最大数量 解法1&#xff1a;哈希 枚举 用一个哈希表统计数组 nums 中的元素及其出现次数。 暴力枚举数组中的数&#xff0c;作为 x&#xff0c;然后不断看 x2,x4,⋯ 在数组中的个数。直到个数不足 2 个为止&a…

CDH6.3.2 多 Spark 版本共存

一 部署Spark客户端 1.1 部署spark3客户端 tar -zxvf spark-3.3.1-bin-3.0.0-cdh6.3.2.tgz -C /opt/cloudera/parcels/CDH/lib cd /opt/cloudera/parcels/CDH/lib mv spark-3.3.1-bin-3.0.0-cdh6.3.2/ spark3将 CDH 集群的 spark-env.sh 复制到 /opt/cloudera/parcels/CDH/li…

C语言系列-文件操作

&#x1f308;个人主页: 会编程的果子君 ​&#x1f4ab;个人格言:“成为自己未来的主人~” 为什么使用文件 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存上&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就会丢失了&#xff0c;等再次运行…

如何内网映射到外网访问?

内网映射到外网访问是一种常见的网络技术&#xff0c;它允许内部网络的资源通过公网进行访问。在某些情况下&#xff0c;我们可能想要访问内部服务器或设备&#xff0c;但由于网络环境的限制&#xff0c;无法直接通过公网访问。此时&#xff0c;内网映射就成为一种解决方案。 天…

Netty源码系列 之 AbstractUnsafe 高低水位线 ChannelOutboundBuffer 源码

目录 AbstractUnsafe.write [注&#xff1a;AbstractUnsafe为Netty定制的Unsafe&#xff0c;非jdk原生的Unsafe] 高低水位线补充 ChannelOutboundBuffer总览 & 高低水位线的剖析 AbstractUnsafe.write [注&#xff1a;AbstractUnsafe为Netty定制的Unsafe&#xff0c;非j…

学习好并用好大模型

大模型是个好东西&#xff0c;学好并用好益处多多~ 1. 运用大模型服务我们的工作 运用大模型服务于工作&#xff0c;可以从以下几个方面着手&#xff1a; 知识管理与检索&#xff1a; 利用大模型强大的自然语言处理能力&#xff0c;建立企业内部的知识库系统。员工可以通过提问…

Python速成篇(基础语法)上

引言 都是我手欠非要报什么python的计算机二级&#xff0c;现在好了假期不但要冲C艹&#xff0c;还要学个python&#xff0c;用了几天的时间速成了一下python的基础语法&#xff0c;其实在学会C的基础上&#xff0c;py学起来是非常的快啊。这篇博客呢&#xff0c;建议有一定语…

Golang 基础 Go Modules包管理

Golang 基础 Go Modules包管理 在 Go 项目开发中&#xff0c;依赖包管理是一个非常重要的内容&#xff0c;依赖包处理不好&#xff0c;就会导致编译失败&#xff0c;本文将系统介绍下 Go 的依赖包管理工具。 我会首先介绍下 Go 依赖包管理工具的历史&#xff0c;并详细介绍下…

Wireshark不显示Thrift协议

使用Wireshark对thrift协议进行抓包&#xff0c;但是只显示了传输层的tcp协议&#xff1a; "右键" -> "Decode As" 选择thrift的tcp端口 将“当前”修改为Thrift&#xff0c;然后点击“确定” 设置后&#xff0c;可以发现Wireshark里面显示的协议从Tcp变…