前言:vue已经放弃维护vue-resource了,然后推荐使用axios,这一推荐不得了了,axios的人气大增啊,在github已经是50多k的star了,axios算是成功打入了vue全家桶了,既然官方这么推荐,我们接下来就来研究一下axios,顺便再啰嗦几句,我们一直在研究这个框架那个框架的,其实说白了,框架其实就是别人的一种编程思想,都是一些大牛总结的一些编程经验,形象一点就比如一辆汽车的高配与低配,都能够跑,但是感觉就是不一样哈,所以多研究别人好的东西能让自己少走很多弯路,还会让自己变得更强,哈哈~~ 加油,骚年!
我们直接用vue-cli创建一个webpack工程(怎么创建一个vue工程我就不bb了哈),然后我们运行我们的vue工程:
接着我们去github上copy一份axios的源码放到我们工程里面。
我们直接把它lib目录的所有文件copy一份:
https://github.com/axios/axios/tree/master/lib
可以看到,我们已经把axios的源码copy进工程了,接下来我们先用一下它,我们先简单用node搭建一个属于自己的服务器(怎么搭建服务器我前面有一篇文章有介绍过,感兴趣的小伙伴可以去看一看node搭建简易服务器,设置跨域访问)
好啦,服务器搭建好了,我们简单的用一下axios:
HelloWorld.vue:
<template>
<div class="hello">
<h1>{
{ msg }}</h1>
</div>
</template>
<script>
import axios from '../lib/axios'
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Axios'
}
},
created () {
axios.get('http://localhost:8090/home').then((res) => {
console.log(res)
}).catch((erro) => {
console.log(erro)
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
好啦,我们运行一下项目可能会报这样的错误(如果是直接用vue-cli创建的工程):
这是因为axios的源码用es5写的,我们工程babel配置文件需要修改一下:
.babelrc
{
"presets": [
[
"env",
{
"modules": false,
"targets": {
"browsers": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
}
],
"stage-2"
],
"plugins": [
"transform-vue-jsx",
[
"transform-runtime",
{
"helpers": false,
"polyfill": false
}
]
]
}
好啦,我们再次运行我们的项目:
可以看到,我们已经请求成功了,axios的用法我就不在这里啰嗦了,小伙伴直接去看axios的文档就好了,我们重点研究一下它是怎么工作了。
首先我们找到axios的入口:
axios.js
'use strict';
var utils = require('./utils');
var bind = require('./helpers/bind');
var Axios = require('./core/Axios');
var mergeConfig = require('./core/mergeConfig');
var defaults = require('./defaults');
/**
* Create an instance of Axios
*
* @param {Object} defaultConfig The default config for the instance
* @return {Axios} A new instance of Axios
*/
function createInstance(defaultConfig) {
var context = new Axios(defaultConfig);
var instance = bind(Axios.prototype.request, context);
// Copy axios.prototype to instance
utils.extend(instance, Axios.prototype, context);
// Copy context to instance
utils.extend(instance, context);
return instance;
}
// Create the default instance to be exported
var axios = createInstance(defaults);
// Expose Axios class to allow class inheritance
axios.Axios = Axios;
// Factory for creating new instances
axios.create = function create(instanceConfig) {
return createInstance(mergeConfig(axios.defaults, instanceConfig));
};
// Expose Cancel & CancelToken
axios.Cancel = require('./cancel/Cancel');
axios.CancelToken = require('./cancel/CancelToken');
axios.isCancel = require('./cancel/isCancel');
// Expose all/spread
axios.all = function all(promises) {
return Promise.all(promises);
};
axios.spread = require('./helpers/spread');
module.exports = axios;
// Allow use of default import syntax in TypeScript
module.exports.default = axios;
可以看到,入口文件其实没有什么内容,当我们在demo使用get请求的时候,我们走了什么内容呢?
created () {
axios.get('http://localhost:8090/home').then((res) => {
console.log(res)
}).catch((erro) => {
console.log(erro)
})
}
那么axios是一个什么的对象呢?我们看到这么一段代码:
function createInstance(defaultConfig) {
//创建一个Axios对象
var context = new Axios(defaultConfig);
//创建一个axios实例
var instance = bind(Axios.prototype.request, context);
//copy一份Axios的原型给instance对象
utils.extend(instance, Axios.prototype, context);
//让instance继承context的所有属性
utils.extend(instance, context);
return instance;
}
通过源码我们可以看到,其实axios对象也就是返回的instance其实原型就是Axios,所以我们接下来看一下Axios。
/core/Axios.js
'use strict';
var utils = require('./../utils');
var buildURL = require('../helpers/buildURL');
var InterceptorManager = require('./InterceptorManager');
var dispatchRequest = require('./dispatchRequest');
var mergeConfig = require('./mergeConfig');
/**
* Create a new instance of Axios
*
* @param {Object} instanceConfig The default config for the instance
*/
function Axios(instanceConfig) {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
/**
* Dispatch a request
*
* @param {Object} config The config specific for this request (merged with this.defaults)
*/
Axios.prototype.request = function request(config) {
/*eslint no-param-reassign:0*/
// Allow for axios('example/url'[, config]) a la fetch API
if (typeof config === 'string') {
config = arguments[1] || {};
config.url = arguments[0];
} else {
config = config || {};
}
config = mergeConfig(this.defaults, config);
config.method = config.method ? config.method.toLowerCase() : 'get';
// Hook up interceptors middleware
var chain = [dispatchRequest, undefined];
var promise = Promise.r