VueAxios

axios 封装和使用

2022-04-18  本文已影响0人  暴躁程序员

1. 配置 axios 实例参数和拦截处理

新建 src/utils/request.js ,代码如下

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'

function errorTips(err) {
  Message({
    message: err.message || '请求失败',
    type: 'error',
    duration: 3000,
  })
}
/*************************** 全局默认配置 ************************************/
// // post请求头
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
// // 请求超时时间
// axios.defaults.timeout = 5000
// // 允许携带cookie
// axios.defaults.withCredentials = true
// // 完整url = base url + request url
// axios.defaults.baseURL = process.env.VUE_APP_BASE_API

/*************************** 实例默认配置 (多服务可创建多个实例)************************************/
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  // baseURL: process.env.NODE_ENV === 'production' ? './' : '/', // 如果前端和后端服务在同服务器环境下可这样配置
  timeout: 5000,
  withCredentials: true,
  headers: {
    post: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
    },
  },
})

// 请求拦截
service.interceptors.request.use(
  config => {
    // 可在此配置 loading 加载动画

    const token = store.state.user.token
    if (token) {
      config.headers.Authorization = token
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截
service.interceptors.response.use(
  response => {
    // 可在此配置 loading 加载结束

    const res = response.data
    if (res.code !== 0) {
      errorTips(res)
      if (res.code === 401 || res.code === 403 || res.code === 404) {
        MessageBox.confirm('登录超时,请重新登录', {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    if (error && error.response) {
      switch (error.response.status) {
        case 400:
          error.message = '请求错误'
          break
        case 401: {
          error.message = '未授权,请登录'
          const router = this.$router
          router.replace({
            path: 'login',
            query: {
              redirect: router.currentRoute.path,
            },
          })
          break
        }
        case 403:
          error.message = '没有权限,拒绝访问'
          break
        case 404:
          error.message = `请求地址出错`
          break
        case 408:
          error.message = '请求超时'
          break
        case 500:
          error.message = '服务器内部错误'
          break
        case 501:
          error.message = '服务未实现'
          break
        case 502:
          error.message = '网关错误'
          break
        case 503:
          error.message = '服务不可用'
          break
        case 504:
          error.message = '网关超时'
          break
        case 505:
          error.message = 'HTTP版本不受支持'
          break
        default:
          break
      }
    }
    errorTips(error)
    return Promise.reject(error)
  }
)

export default service

2. 封装请求 API

新建 src/api/user.js ,代码如下

// 用户模块
import request from '@/utils/request'

export function login(data) {
  return request({
    url: '/api/user/login',
    method: 'post',
    data,
  })
}

export function getInfo(params) {
  return request({
    url: '/api/user/info',
    method: 'get',
    params,
  })
}

export function logout(data) {
  return request({
    url: '/api/user/logout',
    method: 'post',
    data,
  })
}

3. 在组件中使用

方式一:直接在组件中使用
import { getInfo } from '@/api/user'

// 在 methods 中
getUserInfo() {
  const token = this.state.token
  getInfo({token}).then(res => {
      if(res.errorCode === '0'){
        console.log(res.data)
        const { name, avatar } = res.data
      }else{
        console.log('获取信息失败')
      }
  },

方法二:在 Vuex 中使用
  1. 在 src/store/modules/user.js 中调用 API
import { login } from '@/api/user'

// 用户登录
login({ commit }, userInfo) {
  const { username, password } = userInfo
  return new Promise((resolve, reject) => {
    login({ username: username.trim(), password: password })
      .then(response => {
        const { data } = response
        commit('setToken', data.token)
        setToken(data.token)
        resolve()
      })
      .catch(error => {
        reject(error)
      })
  })
},
  1. 在组件中调用 store 下的 user 模块下的 actions 下的 login 方法
handleLogin() {
  this.$refs.loginForm.validate(valid => {
    if (valid) {
      this.loading = true
      this.$store
        .dispatch('user/login', this.loginForm)
        .then(() => {
          this.$router.push({ path: this.redirect || '/' })
          this.loading = false
        })
        .catch(() => {
          this.loading = false
        })
    } else {
      console.log('error submit!!')
      return false
    }
  })
},
上一篇下一篇

猜你喜欢

热点阅读