其他分享
首页 > 其他分享> > vue项目统一管理请求,并附带常用的axios请求封装

vue项目统一管理请求,并附带常用的axios请求封装

作者:互联网

一、前言

一个vue项目里前端请求最起码几十个起步,请求方式也各有不同,为了方便管理,也减轻工作量,比较好的做法是集中管理,在文件中统一管理各类请求,包括请求头参数,参数的携带方式,是否返回blob流等等。

二、实现方法

1、首先创建在项目下untils文件夹创建request.js文件

这里面实现,对请求头的封装,token的添加,请求拦截器
和响应器的相关逻辑,以及axios请求的封装
复制代码

request文件如下

import vue from '@/main'
import axios from 'axios'
import qs from 'qs'
import { Message, MessageBox } from 'element-ui'
import { getToken } from '@/utils/auth'
// getToken是获取存储好的token验证
import { requestSign } from '@/utils/request-sign'
// requestSign 是统一添加请求头标识

// create an axios instance
// 创建一个axios对象
const service = axios.create({
  baseURL: 'api', // (api请求有固定前缀的,可以替换这里)
  timeout: 20000 // request timeout
})
// 设置默认请求头
service.defaults.headers = {
  'Content-Type': 'application/json'
}

// request interceptor  // 设置请求拦截器
service.interceptors.request.use(
  (config) => {
    if (getToken()) {
      config.headers['Authorization'] = getToken() 
      // 让每个请求携带token-- ['Authorization']为自定义key 
      //请根据实际情况自行修改
    }
/**
 * 增加签名,调用requset-sign.js的requestSign方法,
 仅增加头部标识,不改变参数,需要和后端协商,如果没
 有可省略该步骤
 */
    var signHeader = requestSign(
      config.url,
      config.headers['Content-Type'],
      config.data,
      config.params,
    )
    config.headers = Object.assign(config.headers, signHeader)
    // Do something before request is sent
    return config
  },
  (error) => {
    Promise.reject(error)
  },
)

// 请求的响应器
// respone interceptor
service.interceptors.response.use(
  (response) => {
    const res = response.data
    if (response.headers['Authorization']) {
      res['Authorization'] = response.headers['Authorization']
    }
    if (res.code && res.code !== 200) {
      // 需要重新登录;
      if (res.code === 401) {
        MessageBox.alert(res.msg, '提示', {
          confirmButtonText: '确定',
          callback: (action) => {
            vue.$store.dispatch('user/logout')
          }
        })
      } else {
        Message({
          message: res.msg,
          type: 'error',
          duration: 5 * 1000
        })
        return Promise.reject('error')
      }
    } else {
      // 正常情况下,把从接口拿到的数据返回出去
      return response.data
    }
  }, (error) => {
    if (
      error.message &&
      (error.message.indexOf('404') > 10 || error.message.indexOf('406') > 10)
    ) {
      error.message = '数据读取错误,请联系管理员'
    }
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  },
)
/*
这里放封装好的axios请求
*/

export default service
复制代码

2、axios请求封装

axios请求拦截器和响应器都写好了,就可以开始写请求方法的封装了, 常用的get、post、put、patch(用得少,就没封装)、delete五类请求,中间根据参数方式和应用场景的不同,进行对应的封装,用到的service就是前文创建好的axios对象。如下

// post方式,导出blob文件流的,适合下载文件的适合用
export const getExport = (url, params, tout = 999999) => {
  return service({
    method: 'post',
    url: `${url}`,
    data: params,
    timeout: tout,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    transformRequest: [
      function(data) {
        return qs.stringify(data)
      }
    ],
    responseType: 'blob'
  })
}

//参数为query string parameters,接口数据格式要求为raw时
export const postJson = (url, params) => {
  return service({
    method: 'post',
    url: `${url}`,
    data: JSON.stringify(params),
    headers: {
      'Content-Type': 'application/json'
    }
  })
}

//参数为query string parameters,接口数据格式要求为x-www-form-urlencoded时
export const post = (url, params, tout = 20000) => {
  return service({
    method: 'post',
    url: url,
    data: params,
    timeout: tout,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    transformRequest: [
      function(data) {
        return qs.stringify(data)
      }
    ]
  })
}

//参数为query string parameters,接口数据格式要求为form-data时
// post上传表单含文件
export const uploadFile = (url, params) => {
  return service({
    method: 'post',
    url: `${url}`,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
}

//参数为query string parameters,接口数据格式要求为form-data时
// 上传文件同时返回文件
export const uploadImportFile = (url, params, tout = 999999) => {
  return service({
    method: 'post',
    url: `${url}`,
    data: params,
    headers: {
      'Content-Type': 'multipart/form-data'
    },
    timeout: tout,
    responseType: 'blob'
  })
}
// get请求
// 获取返回文件
export const getFile = (url) => {
  return service({
    method: 'get',
    url: `${url}`,
    responseType: 'blob'
  })
}

// put请求
export const put = (url, params) => {
  return service({
    method: 'put',
    url: `${url}`,
    data: JSON.stringify(params),
    headers: {
      'Content-Type': 'application/json'
    }
  })
}

// del请求
export const del = (url, tout = 20000) => {
  return service({
    method: 'delete',
    url: `${url}`,
    timeout: tout
  })
}

// 正常get请求
export const get = (url, params) => {
  return service.get(`${url}`, {
    params: params
  })
}

// get未封装的原始axios请求
export const getUnpack = (url, params) => {
  // 头增加签名
  // var signHeader = signParam(url, '', '', params);
  return axios.get(`${url}`, {
    params: params,
    headers: { 'Authorization': getToken() }
  })
}
复制代码

3、如何使用

a、 在main.js里引入,并全局抛出

  import request from './utils/request' // 封装的axios请求
  
  Vue.prototype.$http = request
  
复制代码

b、在页面中具体使用

  async get() {
     const { data } = await this.$http.post('url', params)
  },
复制代码

this.$http可以用到request.js文件里的方法,比如post,后续跟的是url和参数,如果是get请求,还可以直接将参数放在url里

const { data } = await this.$http.get(`url?参数名=${参数值}`)

复制代码

三、总结

养成良好的编码习惯,将公共的部分都统一管理,会让工作变得更加简单,后期也比较好维护。

ps: 我是地霊殿-三無,希望我能坚持更新。

Snipaste_2022-07-19_15-30-26.jpg


作者:地霊殿__三無
链接:https://juejin.cn/post/7125716343273291807
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:axios,return,请求,service,url,vue,params,data
来源: https://www.cnblogs.com/Earth-Hall-Sanwu/p/16673003.html