前言

vue中ajax请求官方推荐是axios,之前集成的vue-source早被放弃了。axios的用法与jquery-ajax,vue-source的用法均有所不同。为了使用起来更方便,需要对axios简单进行封装。

封装的关键点

1、get 和 post 请求时,传参的方式不同

在get请求中,是使用params: {};在post请求中,使用data: {},至于为啥是这样,不是很清楚,但是官方已经在文档中,有说明:

对于post请求!
这里写图片描述

对于get请求
这里写图片描述

而且,在项目中实际尝试了下,发现当get请求时,必须使用params: {}的方式,而post请求的时候,必须使用data: {}的方式。不然是参数是传递不成功的。

2、post请求传参需要进行处理

当使用post请求时,将发送的请求参数需要使用qs.stringify进行包裹。不然是发送不成功的。

3、post请求的时候,请求头需要设置

4、axios请求没有finally或者always方法

在进行ajax请求的时候,需要有成功,失败,无论成败与否,这三种情况的回调函数。在axios的官方文档中,指出了成功使用.then回调函数,失败使用.catch回调函数,但是没有指出成败与否都执行的回调函数。

当浏览器支持原生的promise的时候,可以用.finally方法来处理成败与否都会执行这种情况,但是当浏览器并不支持promise的时候,则无法使用.finally方法。

在axios的github的一个issue中,有人提出了这个问题,官方给出了解决方法:promise.prototype.finally。

封装后完整的代码

//目录:src/http/http.js

import axios from 'axios';
import qs from 'qs';
require('promise.prototype.finally').shim();

/**
 * 封装axios的通用请求
 * @param  {string}   method     get\post\put\delete
 * @param  {string}   url       请求的接口URL
 * @param  {object}   param     传的参数,没有则传空对象
 */
function http (method, url, param) {
    param = param && typeof param === 'object' ? param : {};
    const config = {
        url: url,
        method: method,
        transformRequest: [function (param) {
            return qs.stringify(param);
        }],
        headers: {
            'X-Requested-With': 'XMLHttpRequest'
        }
    };

    // post请求时需要设定Content-Type
    if (method === 'post') {
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
        config.data = param;
    } else if (method === 'get') {
        config.params = param;
    }

    return axios(config);
}

export {
    http
};

// main.js

import Vue from 'vue';
import { http } from './http/http';
Vue.prototype.$http = http;

// 组件中使用
/**
 * 在组件中发送请求
 * @param  {string}   method     get\post\put\delete
 * @param  {string}   url       请求的接口URL,我们把请求做了开发环境和生产环境的映射,放在urlmap.js中
 * @param  {object}   param     传的参数,没有则传空对象或者不传
 */
this.$http('post', urlmap.get_user_data, {'id': 1, 'ifsid': 2})
.then(res => {
  this.username = res.data.data.username;
})
.catch(err => {
  console.log(err.message);
})
.finally(() => {
  console.log('无论成功与否都会执行');
});

最后,本地开发使用假数据的问题

在前后端分离的情况下,前端进行开发时,需要使用假数据,在vue-cli搭建的项目中,ajax请求的假数据是放在根目录的static目录下。进行开发的时候,发现不能进行post请求,只能进行get请求。同时,当json数据中有备注时,返回结果也解析失败。

解决办法:对webpack.dev.conf.js进行改造,使用json5对返回结果进行处理。

在本地根目录下建一个存放假数据的文件夹mock,在webpack.dev.conf.js中的devServer对象中添加属性:

const fs = require('fs')
const JSON5 = require('json5')

before(app) { // enable to use POST method
  app.use(function (req, res, next) {
      let reg = /\/mock\/\w+\.json/;
      let path = req.path;
      if (reg.test(path)) {
          let result = fs.readFileSync(`.${path}`, 'utf8')
          res.send(JSON5.parse(result));
          next();
      }
      next();
  });
}

另外,我们将项目所需要的ajax请求的url做了一个映射,分为开发环境下的假数据和生成环境下的真实地址,都放在urlmap.js中。

// urlmap.js

// 获取当前执行的环境
const _env = process.env.NODE_ENV;

const devMap = {
    get_user_data: '../../mock/user_data.json'
};

const productionMap = {
    get_user_data: ''
};

export default _env === 'development' ? devMap : productionMap;
Logo

前往低代码交流专区

更多推荐