vue2项目 axios二次封装,接口统一存放,满足RESTful风格(新增源码地址)

一、在新建项目目录src下utils文件夹新建fetch.js文件,此文件统一处理所有http请求和响应。

  • 直接上代码
import axios from 'axios'
import qs from 'qs'
import store from '@/store'
import router from '@/router'
import { getToken } from './auth'
import { Message, MessageBox } from 'element-ui'

const BASE_URL = '/invoice'
const TIMEOUT_MILLISECONDS = 60000 // 超时链接

const instance = axios.create({
  withCredentials: false,
  baseURL: BASE_URL, // 基本url
  timeout: TIMEOUT_MILLISECONDS,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})

二、 axios请求拦截器

instance.interceptors.request.use((config) => {
  // 每个接口新增时间戳
  let timestamp = new Date().getTime()
  if (config.url && config.url.includes('?')) {
    config.url = `${config.url}&t=${timestamp}`
  } else {
    config.url = `${config.url}?t=${timestamp}`
  }
   //PUT POST DELETE方式提交的数据格式化
   if ((config.method === 'post'||config.method === 'put'||config.method === 'delete') && config.headers['Content-Type'] !== 'application/json') {
    config.data = qs.stringify(config.data)
  }
  // 在发送请求之前 判断是否存在token,如果存在的话,则每个http header都加上token
  if (getToken()) {
    // 让每个请求携带token-- ['Authorization']为自定义key 请根据实际情况自行修改
    config.headers['Authorization'] = getToken()
  }
  return config
},
(error) => Promise.reject(error)
)

三、 axios响应拦截器(统一处理所有http响应)

第一种方式

 // 响应拦截器
    instance.interceptors.response.use(response=> {
        const code = response.data.code
        if (code === 401) {
            MessageBox.confirm(
                '登录状态已过期,您可以继续留在该页面,或者重新登录',
                '系统提示', {
                confirmButtonText: '重新登录',
                cancelButtonText: '取消',
                type: 'warning'
            }
            ).then(() => {
                store.dispatch('LogOut').then(() => {
                    if (!window.__POWERED_BY_QIANKUN__) {
                        // 为了重新实例化vue-router对象 避免bug
                        location.reload()
                    } else {
                        window.location.href = '/'
                    }
                })
            })
        } else if (code !== 200) {
            Notification.error({
                title: res.data.msg
            })
            return Promise.reject('error')
        } else {
            return res.data
        }
    },
        error => {
            console.log('err' + error)
            Message({
                message: error.message,
                type: 'error',
                duration: 5 * 1000
            })
            return Promise.reject(error)
        }
    )
    export default instance

第二种方式(所有响应码列出)

instance.interceptors.response.use((response) => {
// 下载类型特殊处理文件名
const type = response.request.responseType || ''
  if (type.includes('blob')) {
    let disposition = response.headers['content-disposition']
    let filename = '默认文件名'
    if (disposition && disposition.indexOf('filename=') !== -1) {
      filename = decodeURI(disposition.substring(disposition.indexOf('filename=') + 9, disposition.length))
    }
    response.data.filename = filename
  }
  return response.data
}, (error) => {
  switch (error.response && error.response.status) {
    case 400:
      error.message = '请求错误(400)'
      Message.error({
        message: error.response.data.msg || error.message
      })
      break
    case 401:
      error.message = '登录信息已过期,请重新登录'// (401)
      MessageBox.confirm(error.response.data.msg || error.message, {
        title: '提示',
        confirmButtonText: '确定',
        showCancelButton: false,
        showClose: false,
        type: 'warning'
      }).then(() => {
       store.dispatch('user/resetToken').then(() => {
            router.push('/login')
          })
      })
      break
    case 403:
      error.message = '拒绝访问(403)'
      break
    case 404:
      error.message = '请求出错(404)'
      break
    case 408:
      error.message = '请求超时(408)'
      Message.error({
        message: error.response.data.msg || error.message
      })
      break
    case 500:
      error.message = '服务器错误(500)'
      Message.error({
        message: error.response.data.msg || error.message
      })
      break
    case 501:
      error.message = '服务未实现(501)'
      break
    case 502:
      error.message = '网络错误(502)'
      break
    case 503:
      error.message = '服务不可用(503)'
      break
    case 504:
      error.message = '网络超时(504)'
      break
    case 505:
      error.message = 'HTTP版本不受支持(505)'
      break
  }
  if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
    Message.error({
      message: '网络异常'
    })
  }
  return Promise.reject(error)
})
export default instance

四、在src目录下新建api文件夹,在新建index.js/urlConst.js文件

  • urlConst.js 存放api接口路径
const urlConst = {
  /**
   * 公共模块API
   **/
  // 发送短信校验码
  sendPhoneVerify: '/sms/send-phone-verify',
  // 校验短信验证码
  verifyCode: '/sms/verify-code',
  // 获取法人手机号码(1.3版本新增接口)
  getLegalPhone: '/enterprise/legal-phone',
  // 获取企业信息
  current: '/user/current'
  ......
}
export default urlConst
  • index.js封装通用请求方法
import fetch from '@/utils/fetch'
import urlConst from './urlConst' // api路径定义文件
const urlConfig = {
  ...urlConst
}
/**
 * 通用请求方法
 * @param {methodType} 请求方式
 * @param {urlName} 接口名称
 * @param {dataParams} 正常传参
 * @param {urlParam} url参数restFul风格
 */
/* 通用请求方法 */
export function ajaxRequest (methodType, urlName, dataParams, urlParam) {
  methodType = methodType.toUpperCase()
  dataParams = dataParams || ''
  urlParam = urlParam || ''
  let requestConfig = {
    method: methodType
  }
  let url = urlConfig[urlName]
  requestConfig.url = urlParam ? (url + '/' + urlParam) : url
  switch (methodType) {
    case 'POST':
    case 'PUT':
    case 'DELETE':
      requestConfig.headers = { 'Content-Type': 'application/json' }
      requestConfig.data = dataParams
      break
    case 'GET':
      requestConfig.headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
      requestConfig.params = dataParams
      break
    case 'UPLOAD':
      requestConfig.headers = { 'Content-Type': 'application/form-data' }
      requestConfig.method = 'POST'
      requestConfig.data = dataParams
      break
    // 下载excel zip
    case 'DOWNLOAD':
      requestConfig.headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
      requestConfig.method = 'GET'
      requestConfig.params = dataParams
      requestConfig.responseType = 'blob'
      break
    // 下载回显图片
    case 'GETIMAGE':
      requestConfig.headers = { 'Content-Type': 'application/json' }
      requestConfig.method = 'GET'
      requestConfig.params = dataParams
      requestConfig.responseType = 'blob'
      break
    default:
      requestConfig.headers = { 'Content-Type': 'application/json' }
      requestConfig.method = 'POST'
      requestConfig.data = dataParams
      break
  }
  return fetch(requestConfig)
}

五、将封装的axios挂载在main.js中,供全局使用

import { ajaxRequest } from '@/api'
Vue.prototype.$ajaxRequest = ajaxRequest

六、 在文件中直接使用this.$ajaxRequest(),例如

1、正常方式请求接口

// 修改密码
 async changePassword (params) {
      const res = await this.$ajaxRequest('put', 'changePassword', params)
      注释:
      put 是请求方式
      changePassword 是定义的接口名
      params 是接口所需要的参数
    }

2、RESTful风格请求接口

// 获取节假日
    async checkIsHoliday (date) {
      let dateValue = moment(date).format('YYYYMMDD')
      const res = await this.$ajaxRequest('get', 'getIsHoliday', '', dateValue)
       注释:
      get 是请求方式
      getIsHoliday 是定义的接口名
      '' 是正常接口所需要的参数
      dateValue 是restful风格需要的参数
    }

七、源码地址

vue2后台管理系统模板

vue3后台管理系统模板

八、相关文章

基于elementUI中table组件二次封装(Vue项目)


keep-alive不能缓存多层级路由(vue-router)菜单问题解决


基于ElementUi再次封装基础组件文档

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Vue2封装Axios接口请求的二次封装可以让我们在项目中更加方便地使用Axios进行数据请求,同时也可以提高代码的可维护性和复用性。下面是一个简单的Vue2封装Axios接口请求的示例: 1. 安装Axios项目中安装Axios,可以使用npm或者yarn进行安装: ```bash npm install axios --save ``` 或者 ```bash yarn add axios ``` 2. 封装Axios 在src目录下新建一个api文件夹,用于存放Axios封装代码。在api目录下新建一个request.js文件,用于封装Axios的请求方法。 ```javascript import axios from 'axios' // 创建实例 const service = axios.create({ baseURL: process.env.BASE_URL, // 接口的基础路径 timeout: 5000 // 请求超时时间 }) // 请求拦截器 service.interceptors.request.use( config => { // 在请求发送之前做一些处理,比如添加token等 return config }, error => { // 请求错误时做些事 return Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( response => { // 对响应数据做一些处理,比如说判断返回的状态码是否正确等 return response.data }, error => { // 响应错误时做些事 return Promise.reject(error) } ) export default service ``` 在上面的代码中,我们使用了Axios的interceptors来拦截请求和响应,并做一些处理。比如说,在请求拦截器中,我们可以在发送请求之前添加token等信息;在响应拦截器中,我们可以对返回的数据进行处理,判断响应状态码是否正确等。 3. 封装API请求 在api目录下新建一个index.js文件,用于封装API请求的方法。我们可以根据实际的业务需求,封装不同的请求方法。 ```javascript import request from './request' export function getUsers () { return request({ url: '/users', method: 'get' }) } export function getUserById (id) { return request({ url: `/users/${id}`, method: 'get' }) } export function createUser (data) { return request({ url: '/users', method: 'post', data }) } // 其他API请求方法... ``` 在上面的代码中,我们使用了封装的request方法来发送请求,同时根据业务需求,定义了不同的请求方法,比如获取用户列表、根据ID获取用户信息、创建用户等。 4. 使用API请求 在Vue组件中使用API请求非常简单,只需要在组件中引入封装API请求,然后调用对应的方法即可。 ```javascript import { getUsers } from '@/api' export default { mounted () { this.getUsers() }, methods: { async getUsers () { const { data } = await getUsers() console.log(data) } } } ``` 在上面的代码中,我们在组件中引入了封装的getUsers方法,并在mounted钩子函数中调用该方法来获取用户列表,并将返回的数据打印到控制台上。 这样,我们就完成了Vue2封装Axios接口请求的二次封装。通过对Axios进行二次封装,我们可以更加方便地使用Axios进行数据请求,并且也可以提高代码的可维护性和复用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wocwin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值