小知识vueVUE

axios进一步封装

2019-08-01  本文已影响80人  前端艾希

About

在实际项目开发中,为了减少代码量与更好的管理接口,我们一般会根据项目需求对axios进行一定封装,本文介绍了axios的封装方式供新手参考。

一、建立接口管理的JS文件

以前我们在项目中一般都会有一个JS文件专门存放我们的接口,当我们需要添加或者删除,更改接口的时候,直接到该文件中进行修改,非常的方便。

// src/api/api.js
const api = {
  // 获取城市选择页面列表内容
  getCityInfo: {
    method: 'get',
    url: '/city.json'
  },
  // 获取首页数据
  getHomeInfo: {
    method: 'get',
    url: '/index.json'
  },
  // 获取城市详情页面数据
  getDetailInfo: {
    method: 'get',
    url: '/detail.json'
  },
  // 获取搜索页面城市热搜数据
  getHotInfo: {
    method: 'get',
    url: '/hotSearch.json'
  }
}
export default api

二、axios封装

直接看注释吧

// api/config
import axios from 'axios'
import service from './api'
import { Toast } from 'vant' // 为了优化用户体验,引入有赞组件

const Token = sessionStorage.getItem('token') // 从sessionStorage中取出token

let instance = axios.create({  // 实例化一个axios
  baseURL: 'http://localhost:8080/api',
  timeout: 1000,
  Token
})
const Http = {} // 声明一个接口容器

for (let key in service) {  // 遍历接口文件,获取每一个接口 
  let api = service[key]
  Http[key] = async function (  // 将接口作为key写入到接口容器中,key对应的是一个函数
    params, // 将来使用接口时传入的参数
    isFormData = false, // 是否采用formdata的格式
    config = {}
  ) {
    let newParams = {}  // 不确定在调用接口时是否传入了参数,这里声明一个新的params
    if (params && isFormData) { // 如果条件成立说明有formdata形式的数据需要推送
      newParams = new FormData()
      for (let i in params) {  // 将传入的数据转成formdata
        newParams.append(i, params[i])
      }
    } else {
      newParams = params    // 如果不是formdata则不需要对params进行操作    
    }

    let response = {}
    // 因为put、post以及patch都是向服务端推送数据,需要的参数一样,所以这里分开写一下
    if (api.method === 'put' || api.method === 'post' || api.method === 'patch') {
      try {
        response = await instance[api.method](api.url, newParams, config)
      } catch (err) {
        response = err  // 如果请求错误就将错误返回
      }
    } else {
      config.params = newParams
      try {
        response = await instance[api.method](api.url, config)
      } catch (err) {
        response = err
      }
    }
    return response // 请求成功返回res
  }
}

// 请求拦截器
instance.interceptors.request.use(config => {
  Toast.loading({   // 请求后就显示toast
    mask: false,
    duration: 0, // 一直显示toast
    forbidClick: true, // 禁止点击
    message: '加载中...'
  })
  return config
}, () => {
  // 请求错误后,首先清除之前的toast
  Toast.clear()
  Toast('请求错误,请求稍后重试')   // 显示错误的toast
})
// 响应拦截器
instance.interceptors.response.use(res => {
  // 请求成功
  Toast.clear()
  return res.data
}, () => {
  Toast.clear()
  Toast('请求错误,请求稍后重试')
})

export default Http // 导出Http这个对象

三、调用接口

一般来说我们每个页面都会有请求数据,所以这里直接把接口挂载到Vue的原型上

// ../main.js
import http from '@/api/config'

Vue.prototype.$http = http

这样我们在组件中就不需要导入http而可以直接使用了

// @/pages/home/Home.vue

methods: {
    async getInfo () {
      let res = await this.$http.getHomeInfo()  // 调用接口,并且把返回值赋值给res
      this.getInfoSucc(res)   
    },
    getInfoSucc (res) {
      const {data} = res
      this.swiperList = data.swiperList
      this.iconList = data.iconList
      this.recommendList = data.recommendList
      this.favList = data.favList
      this.weekendList = data.weekendList
    }
}

created () {
    this.getInfo()
}

四、效果对比

1. 使用封装后的axios请求

拦截器显示toast.gif

2. 使用原生axios

原生axios效果.gif

参考链接

作者:小吕12
连接:https://github.com/web-gm/axios-learn.git

上一篇下一篇

猜你喜欢

热点阅读