vue3 + Element-plus 开发后台管理系统(14)

420 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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>

到此,用户头像和对应的下拉菜单就已经实现完成了,下一步就是完成我们的退出登录功能