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>

image-20201018153821660

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/#拦截器

官方解释

拦截器

在请求或响应被 thencatch 处理前拦截它们。

什么意思呢?也就是说在请求或响应,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')

posted @ 2020-10-18 15:39  makalo  阅读(223)  评论(0编辑  收藏  举报