资讯专栏INFORMATION COLUMN

vue中axios请求的封装

hover_lew / 3047人阅读

摘要:整合,最终得到的对象如下注意模块名和没有了,所以需要注意命名的唯一,以免覆盖。如下,,由于我司后台提供的接口大都是和,所以只考虑了这两种请求方式在中创建一个,并在中引用发送请求

1.发送请求模块目录

2.@/api/url中存放的是每个模块的URL
// 商品模块 product.js
const product = {
  sku: {
    list: "/product/product/speclist",
    options: "/product/product/options"
  }
}
export default product

// 公用请求模块 common.js
const common = {
  region: {
    provinces: "/region/region/list",
    cities: "/region/region/list"
  },
  upload: {
    image: "/product/product/upload"
  }
}
export default common

发送请求的时候只需要指定key(sku/list),如:this.$ajax("sku/list", param);假定axios设置的baseURL是http://prod.storm.com/api/,那么最终的请求地址:http://prod.storm.com/api/product/product/speclist

3.requireURLs.js

使用webpack提供的require.context将src/api/url下后缀为js的所有文件引入,并整理出一个对象。

let urls = {}
const req = require.context("./url", false, /.js$/)

const requireAll = requireContext => requireContext.keys().map(i => {
  let url = requireContext(i)
  Object.assign(urls, url.default)
})
requireAll(req)
export default urls

整合common.js & product.js,最终得到的对象如下:

urls = {
  sku: {
    list: "/product/product/speclist",
    options: "/product/product/options"
  },
  region: {
    provinces: "/region/region/list",
    cities: "/region/region/list"
  },
  upload: {
    image: "/product/product/upload"
  }
}
// 注意:模块名product和common没有了,所以需要注意命名的唯一,以免覆盖。
4.ajax.js
import axios from "axios"
import qs from "qs"
import jsd from "js-file-download"
import store from "@/store"
import urlObj from "./requireURLs"
import { Message, MessageBox } from "element-ui"
import { getToken } from "@/utils/auth"

const service = axios.create({
  baseURL: `${process.env.BASE_API}/api/`, // 不同环境(dev/prod/test)使用不同的baseURL
  timeout: 5000
})
service.interceptors.request.use(
  config => {
    // 上传文件时,config.data的数据类型是FormData,
    // qs.stringify(FormData)的结果是空字符串,导致接口报**参数为空**的错误
    if (config.method === "post" && config.data.constructor !== FormData) {
      config.data = qs.stringify(config.data)
    }
    if (store.getters.token) {
      config.headers.common["Auth-Token"] = getToken()
      // Auth-Token 登录过期后,重新登录不传token
      if (!config.headers.common["Auth-Token"]) {
        delete config.headers.common["Auth-Token"]
      }
    }
    return config
  },
  error => {
    Promise.reject(error)
  }
)
service.interceptors.response.use(
  response => {
    const res = response.data // 后台会把{ code, data, msg }返回到response.data中
    if (response.headers["content-type"].indexOf("application/vnd.ms-excel") !== -1) {
      // 通过请求接口下载Excel,由于后台返回的数据中(res)没有code(我也不知道为什么,反正后台就说没有),所以我只好通过响应头的content-type判断了
      // 下载接口返回的response header如下(后台把文件名放在Content-Disposition中(filename))
      // Content-Disposition: attachment; filename=20190323211209.csv
      // Content-Type: application/vnd.ms-excel;charset=GBK
      let fileName = response.headers["content-disposition"].split("=")[1]
      jsd(res, fileName)
      return
    }
    if (res.code === 0) { // 和后台约定code:0代表请求成功
      return res
    } else {
      if (res.code === 18500) { // 和后台约定code:18500代表token未过期,但是被更新了
        handleLogin("您已被登出,请重新登录")
      } else if (res.code === 18501) { // 和后台约定code:18500代表token过期
        handleLogin("登录已失效,请重新登录")
      } else {
        // 统一处理接口的报错信息,如果需要具体到页面去处理,可以和后台另外约定一个code
        Message({
          message: res.msg,
          type: "error",
          duration: 3 * 1000
        })
      }
      return Promise.reject(res)
    }
  },
  error => {
    let data = error.response.data
    Message({
      message: data.msg,
      type: "error",
      duration: 3 * 1000
    })
    return Promise.reject(data)
  }
)

const handleLogin = title => {
  MessageBox.confirm(title, "提示", {
    confirmButtonText: "重新登录",
    showCancelButton: false,
    showClose: false,
    type: "warning"
  }).then(() => {
    store.dispatch("FedLogout").then(() => {
      location.reload()
    })
  })
}

const ajax = (path, data = {}, options = {}) => {
  // 如果path以http开头指定了一个url,直接用;否则就去遍历步骤3中的urls对象。如下:
  // this.$ajax("http://test.storm.com"),url = "http://test.storm.com"
  // this.$ajax("sku/list"),url = "/product/product/speclist"
  let url = path.indexOf("http") === -1 ? path.split("/").reduce((o, k) => {
    return o[k]
  }, urlObj) : path
  let method = options.method || "post"
  let params = { url, method }
  
  // 由于我司后台提供的接口大都是post和get,所以只考虑了这两种请求方式
  if (options.method === "get") {
    Object.assign(params, { params: data }, options)
  } else {
    // post
    Object.assign(params, { data }, options)
  }
  return service(params)
}

export default ajax
5.在src/plugins中创建一个ajaxPlugin.js,并在src/main.js中引用
// ajaxPlugin.js
import ajax from "@/api/ajax"

let ajaxPlugin = {}

ajaxPlugin.install = Vue => {
  Vue.prototype.$ajax = ajax
}

export default ajaxPlugin

// main.js
import ajaxPlugin from "@/plugins/ajaxPlugin"

Vue.use(ajaxPlugin)
6.发送请求:
this.$ajax("sku/list").then(res => {})

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102883.html

相关文章

  • Spring Boot + Vue 前后端分离开发,前端网络请求封装与配置

    摘要:今天松哥就带大家来看看的使用。此时启动前端项目,就可以顺利发送网络请求了。松哥将自己封装的网络请求库已经放在上,欢迎大家参考。前端网络访问,主流方案就是 Ajax,Vue 也不例外,在 Vue2.0 之前,网络访问较多的采用 vue-resources,Vue2.0 之后,官方不再建议使用 vue-resources ,这个项目本身也停止维护,目前建议使用的方案是 axios。今天松哥就带大...

    Ku_Andrew 评论0 收藏0
  • vue + axios---封装一个http请求

    摘要:在使用开发时,官方推荐使用来请求接口官方地址但是并不像一样拥有,即不能直接来使用,所以需要我们自己根据来写一个具有方法的库。 在使用vue开发时,官方推荐使用axios来请求接口 // axios官方地址 https://github.com/axios/axios 但是axios并不像 vue-resource 一样拥有install,即不能直接 Vue.use(axios) ...

    Scliang 评论0 收藏0
  • vue封装axios基本思路

    Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。在vue项目之中使用axios是一个非常明智的选择,因为vue官方已经宣称不再维护vue-resource,并且推荐使用axios. 1 为什么选择axios? 使用axios可以统一做请求-响应拦截,例如响应时我们将响应信息拦截起来,判断状态码,从而弹出报错信息 设定请求超时,例如3000ms未响应...

    microcosm1994 评论0 收藏0
  • vue-cli怎么基于axios封装方法

    摘要:大家好,我是,潜水于掘金和思否的一名前端小小生,今天看了几篇文章关于中怎么去封装,视乎好多版本都是基于去做的。 **大家好,我是minijie,潜水于掘金和思否的一名前端小小生,今天看了几篇文章关于vue中怎么去封装axios,视乎好多版本都是基于promise去做的。这让我很疑惑,axios不就是基于promise的一个请求库吗?为啥还要多一层promise呢?下面是根据我自己的想法...

    baiy 评论0 收藏0
  • 从0到1使用VUE-CLI3开发实战(四): Axios封装

    摘要:从到使用开发实战四封装有很多同学看了本系列的前几篇之后建议我暂时先不用,于是小肆之后将把换成继续下面的文章。前置阅读用从到做一个完整功能手机站一从到开发实战手机站二提交规范配置从到使用开发实战三知识储备 从0到1使用VUE-CLI3开发实战(四): Axios封装 有很多同学看了本系列的前几篇之后建议我暂时先不用TS,于是小肆之后将把TS换成JS继续下面的文章。今天给大家带来项目中非常...

    ThinkSNS 评论0 收藏0
  • 二次封装axios,根据参数来实现多个请求多次拦截

    摘要:新建文件,设置请求拦截和处理的逻辑取消请求设置默认请求头,如果不需要可以取消这一步请求超时的时间限制开始设置请求发起的拦截处理代表发起请求的参数的实体得到参数中的字段,用于决定下次发起请求,取消对应的相同字段的请求如果没有就默认添加一个 1. 新建 axiosTool.js 文件,设置请求拦截和处理的逻辑 import Vue from vue import axios from ax...

    MoAir 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<