携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
搭建Layout架构 解决方案与实现
获取用户基本信息
处理完了基本的 Layout 架构之后,接下来我们实现一下 navbar 中的头像功能
这样一个功能主要分为三个部分:
1、获取并展示用户信息
2、element-plus 中的 dropdown 组件的使用
3、退出登录的方案实现
那么就下来我们就先从第一部分开始看
- 获取并展示用户信息
这里我们将其分为三个方面进行实现
1、定义接口请求方法
在 api/sys.js 中定义如下方法
/**
* 获取用户信息
*/
export const getUserInfo = () => {
return request({
url: '**/**'
})
}
因为获取用户信息需要对应的 token,所以我们可以利用 axios 的请求拦截器对 token 进行统一注入,在 utils/request.js 中写入如下代码
import store from '@/store'
// 请求拦截器
service.interceptors.request.use(
config => {
// 在这个位置需要统一的去注入token
if (store.getters.token) {
// 如果token存在 注入token
config.headers.Authorization = `Bearer ${store.getters.token}`
}
return config // 必须返回配置
},
error => {
return Promise.reject(error)
}
)
2、定义调用接口的动作
在 store/modules/user 中写入以下代码
import { login, getUserInfo } from '@/api/sys'
export default {
namespaced: true,
state: () => ({
userInfo: {}
}),
mutations: {
setUserInfo(state, userInfo) {
state.userInfo = userInfo
}
},
actions: {
async getUserInfo(context) {
const res = await getUserInfo()
this.commit('user/setUserInfo', res)
return res
}
}
}
3、在权限拦截时触发动作
在 permission.js 中写入以下代码
if (to.path === '/login') {
} else {
// 判断用户资料是否获取
// 若不存在用户信息,则需要获取用户信息
if (!store.getters.hasUserInfo) {
// 触发获取用户信息的 action
await store.dispatch('user/getUserInfo')
}
next()
}
}
在 store/getters.js 中写入
const getters = {
userInfo: state => state.user.userInfo,
/**
* @returns true 表示已存在用户信息
*/
hasUserInfo: state => {
return JSON.stringify(state.user.userInfo) !== '{}'
}
}
注:如果使用中出现 401 之类的报错,其实表示的是登录超时
如遇到此错误,可以手动清除 LocalStorage 中的 token 后再刷新页面重新操作,此时我们就能看到用户信息数据了
渲染用户头像菜单
现在我们已经获取到了用户数据,并且在 getters 中做了对应的快捷访问,那么接下来我们就可以根据数据渲染用户头像
渲染用户头像,我们将用到 element-plus 的两个组件
1、avatar
2、Dropdown
在 layout/components/NavBar/index.vue 中写入以下代码
<template>
<div class="navbar">
<div class="right-menu">
<!-- 头像 -->
<el-dropdown class="avatar-container" trigger="click">
<div class="avatar-wrapper">
<el-avatar
shape="square"
:size="40"
:src="$store.getters.userInfo.avatar"
></el-avatar>
<i class="el-icon-s-tools"></i>
</div>
<template #dropdown>
<el-dropdown-menu class="user-dropdown">
<router-link to="/">
<el-dropdown-item> 首页 </el-dropdown-item>
</router-link>
<el-dropdown-item divided>
退出登录
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script setup>
import {} from 'vue'
</script>
<style lang="scss" scoped>
.navbar {
height: 50px;
overflow: hidden;
position: relative;
background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.right-menu {
display: flex;
align-items: center;
float: right;
padding-right: 16px;
::v-deep .avatar-container {
cursor: pointer;
.avatar-wrapper {
margin-top: 5px;
position: relative;
.el-avatar {
--el-avatar-background-color: none;
margin-right: 12px;
}
}
}
}
}
</style>
到此,用户头像和对应的下拉菜单就已经实现完成了,下一步就是完成我们的退出登录功能