ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-09-09 15:32:42  阅读:235  来源: 互联网

标签:axios return 请求 service url vue params data


一、前言

一个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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有