系统搭建---axios的封装

82 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

菜鸡一个,轻喷,纯粹记录

1. Axios网络请求库封装

// src/utils/service.ts
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElLoading } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { localStorage } from './localStorage'
//1. 创建实例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_URL,
  timeout: 5000,
  headers: { 'Content-Type': 'application/json;charset=utf-8' }
  // showLoading!: true,
})
// 2. 请求拦截器
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    // console.log(config, '-----')
    const token = localStorage.get('JSPH_EDU_TOKEN')
    if (token) {
      config.headers!.Authorization = `Bearer ${token}`
    }
    //这里的 config 一定要 return 出去
    return config
  },
  (err) => {
    ElMessage.error(err.message) // 提示错误信息
    return Promise.reject(err) // 请求错误让请求走到catch而不是then
  }
)
// 3. 响应拦截器
service.interceptors.response.use(
  (res: AxiosResponse) => {
    // 响应数据为二进制流处理(Excel导出)
    // return res
    if (res.data instanceof ArrayBuffer) {
      return res
    } else {
      return res.data
    }
  },
  (err) => {
  // 根据自己需要写仅仅参考
    if (err && err.response) {
      switch (err.response.status) {
        case 400:
          err.message = err.response.data
          break
        case 401:
          err.message = '授权失败,请重新登录'
          break
        case 403:
          err.message = '拒绝访问'
          break
        case 404:
          err.message = '请求错误未找到该资源'
          break
        case 500:
          err.message = '服务端出错'
          break
      }
    } else {
      err.message = '连接服务器出错'
    }
    ElMessage.error(err.message)
    console.log(err, '响应拦截器err')
    return Promise.reject(err && err.response) // 请求错误让请求走到catch而不是then
  }
)
export default service
  1. 创建实例:里面的baseurl:import.meta.env.VITE_APP_BASE_URL获取当前环境的请求基地址 timeout:超时时间 headers:请求头headers
  2. service.interceptors.request.use:请求拦截器,在请求前做一些事情,注入token等,还有主要是要记得 return config
  3. service.interceptors.response.use:响应拦截器,请求回的数据,和错误的一些统一处理,

2. 请求封装(主要就是登录请求,获取用户信息和用户菜单,后面需要动态路由权限设置)

// api/login/index.ts
import request from '@/utils/request'
//  登录
export function accountLogin(data: object) {
  return request({
    url: '/login',
    method: 'POST',
    data
  })
}
// 请求用户信息
export const requestInfoById = (id: number) => {
  return request({
    url: '/users/' + id
  })
}
// 请求用户菜单
export const requestInfoMenu = (id: number) => {
  return request({
    url: `/role/${id}/menu`
  })
}

3. 使用(我是在pina里面使用的,这个我也不太懂,都是看官网上找的信息)

// store/module/user.ts
import { defineStore } from 'pinia'
// 请求接口数据
import { accountLogin, requestInfoById, requestInfoMenu } from '@/api/login'
import { UserState } from './type'
// 自己封装的 localStorage ,很简单,就不放了
import { localStorage } from '@/utils/localStorage'
import router, { constantRoutes } from '@/router'
import { mapMenusToRoutes } from '@/utils/map-menus'
const useUserStore = defineStore({
  id: 'user',
  state: (): UserState => ({
    token: '',
    nickName: '',
    userInfo: {}, // 用户信息
    userMenu: {} // 用户菜单
  }),
  actions: {
    // 执行登录操作
    async userLogin(formData: any) {
      // 1. 登录
      const { data } = await accountLogin(formData)
      this.nickName = data.name
      this.token = data.token
      localStorage.set('JSPH_EDU_TOKEN', data.token)
      ```
      // 2. 获取用户信息
      const userInfo = await requestInfoById(data.id)
      localStorage.set('JSPH_EDU_USERINFO', userInfo.data)
      this.userInfo = userInfo.data
      // 3. 获取用户菜单权限
      // const userMenu = await requestInfoMenu(userInfo.data.role.id)
      // localStorage.set('JSPH_EDU_USERMENU', userMenu.data)
      // this.userMenu = userMenu.data