axios 的使用
我们在构建应用时需要访问一个 API 并展示其数据。做这件事的方法有好几种,而使用基于 Promise 的 HTTP 客户端 axios 则是其中非常流行的一种。
直接使用cdn
现在我们结合json-server来测试
json-server :https://www.cnblogs.com/makalochen/p/13835426.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios</title>
</head>
<body>
</body>
<!--直接使用github上面提供的CDN-->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 获取tb1全部数据
axios.get('http://localhost:3000/tb1')
.then((data)=>{
console.log(data);
});
// 获取tb1的id为1一条数据
axios.get('http://localhost:3000/tb1/1')
.then((data)=>{
console.log(data);
})
// get 带参数
axios.get('http://localhost:3000/tb1/1',{params: {
pageNow : 1,
pageSize : 10,
}}).then((data)=>{
console.log(data);
})
// 添加一条数据到tb1
axios.post('http://localhost:3000/tb1',{stat:false,title:'喝水'})
.then((d)=>{
console.log(d);
}).catch(error => console.log(error))
// 删除一条数据
axios.delete('http://localhost:3000/tb2/1')
.then((d)=>{
console.log(d);
}).catch(error => console.log(error))
// 修改一条数据
axios.put('http://localhost:3000/tb1/1',{title:'修改后的标题'})
.then((d)=>{
console.log(d);
}).catch(error => console.log(error))
</script>
</html>
vue全局使用axios的方法
在vue项目开发中,我们使用axios进行ajax请求,很多人一开始使用axios的方式,会当成vue-resoure的使用方式来用,即在主入口文件引入import VueResource from 'vue-resource'之后,直接使用Vue.use(VueResource)之后即可将该插件全局引用了,所以axios这样使用的时候就报错了,很懵逼。
仔细看看文档,就知道axios 是一个基于 promise 的 HTTP 库,axios并没有install 方法,所以是不能使用vue.use()方法的。☞查看vue插件
那么难道我们要在每个文件都要来引用一次axios吗?多繁琐!!!解决方法有很多种:
1.结合 vue-axios使用
2.axios 改写为 Vue 的原型属性
3.结合 Vuex的action
1.结合 vue-axios使用
http://www.axios-js.com/zh-cn/docs/vue-axios.html
npm install --save axios vue-axios
看了vue-axios的源码,它是按照vue插件的方式去写的。那么结合vue-axios,就可以去使用vue.use方法了
首先在主入口文件main.js中引用:
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios,axios);
之后就可以使用了,在组件文件中的methods里去使用了:
getNewsList(){
this.axios.get('api/getNewsList').then((response)=>{
this.newsList=response.data.data;
}).catch((response)=>{
console.log(response);
})
}
2.axios 改写为 Vue 的原型属性(不推荐这样用)
首先在主入口文件main.js中引用,之后挂在vue的原型链上:
import axios from 'axios'
Vue.prototype.$ajax= axios
在组件中使用:
this.$ajax.get('api/getNewsList')
.then((response)=>{
this.newsList=response.data.data;
}).catch((response)=>{
console.log(response);
})
结合 Vuex的action
在vuex的仓库文件store.js中引用,使用action添加方法
import Vue from 'Vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
const store = new Vuex.Store({
// 定义状态
state: {
user: {
name: 'xiaoming'
}
},
actions: {
// 封装一个 ajax 方法
login (context) {
axios({
method: 'post',
url: '/user',
data: context.state.user
})
}
}
})
export default store
在组件中发送请求的时候,需要使用 this.$store.dispatch
methods: {
submitForm () {
this.$store.dispatch('login')
}
}
vue 使用 axios的拦截器
官方文档:http://www.axios-js.com/zh-cn/docs/#拦截器
官方解释
拦截器
在请求或响应被
then
或catch
处理前拦截它们。
什么意思呢?也就是说在请求或响应,then或者catch处理之前我们做些操作。
比如现在有个这样两个需求
-
在所有请求上带上一个请求头
-
在所有响应数据中判断如果返回状态码为401则跳转登录路由
你想怎么实现?每个请求中去写一遍,显然不可能使用这种写法,这时候拦截器的作用就出来了
第一个需求使用请求拦截器,第二需求使用响应拦截器
请求拦截器
官方例子
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
实现在所有请求上带上一个请求头
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
//获取token
const token = localStorage.getItem('base_admin_token');
if (token) {
//设置Authorization请求头
config.headers.Authorization = token
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
响应拦截器
官方例子
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
实现在所有响应数据中判断如果返回状态码为401则跳转登录路由
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
//响应数据
const data = response.data;
data.code = 401;
if (data.code === 401) {
//避免重复切换
//console.log(router, '路由.....');
//路由跳转 跳转地址相同会报错,所以捕获一下
router.push({path: '/login'}).catch(err => { console.log(err) });
}
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
完整的main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
//引入antd
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
//引入axios
import axios from 'axios';
import VueAxios from 'vue-axios';
//引入自定义接口地址
import urls from './config/urls';
Vue.config.productionTip = false
//axios 拦截器
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
//获取token
const token = localStorage.getItem('base_admin_token');
if (token) {
//设置Authorization请求头
config.headers.Authorization = token
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
//响应数据
const data = response.data;
data.code = 401;
if (data.code === 401) {
//避免重复切换
//console.log(router, '路由.....');
//路由跳转 跳转地址相同会报错,所以捕获一下
router.push({path: '/login'}).catch(err => { console.log(err) });
}
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
//全局引入
Vue.use(Antd);
Vue.use(VueAxios,axios);
//设置到vue全局属性
Vue.prototype.urls = urls.urls;
//创建vue 并 使用路由将路由挂载到app 组件
new Vue({
router,
render: h => h(App)
}).$mount('#app')