【axios】Vue项目中封装和使用axios

在之前我们讲过axios的基本使用方法【axios】axios的基本使用,在实际的Vue项目中,我们并不使用这种方法。当时还未实现项目的规范化,没有严格划分组件和模块,只是把所有东西都写在一个html文件中,现在我们要从前端工程化的角度来看如何使用axios。

零、准备工作

假设我们有一个Vue项目,App根组件中包含一个Left组件和一个Right组件,Left组件中有一个按钮,点击后发送GET请求。Right组件中有一个按钮,点击后发送POST请求。基本页面构成如下:
【axios】Vue项目中封装和使用axios_第1张图片

首先需要安装axios包,后续才可以在项目中使用axios。在终端执行npm i axios -S,即可把axios安装到项目中。

一、在需要发送请求的.vue组件中导入axios并使用

Left组件的script标签内容:

<script>
// 导入axios模块
import axios from 'axios'

export default {
  data() {
    return {
      bookList: {}
    }
  },
  methods: {
  	// 点击事件
  	// 
    async getInfo() {
      const { data: res } = await axios.get('http://www.liulongbin.top:3006/api/getbooks')
      console.log(res)
      // 一般把请求回来的数据转存到data中
      this.bookList = res
    }
  }
}
script>

Right组件的script标签内容:

<script>
// 导入axios模块
import axios from 'axios'

export default {
  methods: {
  	// 点击事件
  	// 
    async postInfo() {
      const { data: res } = await axios.post('http://www.liulongbin.top:3006/api/post', { name: 'zs', age: 20 })
      console.log(res)
      // 不再演示数据转存到data的过程
    }
  }
}
script>

【axios】Vue项目中封装和使用axios_第2张图片
均可以成功请求,但是这种方法的缺点是:每使用一次axios,就要导入一次,只要这个.vue组件使用了axios,就需要导入axios模块,各组件之间不能互相使用(不通用),比较麻烦。因此我们希望axios全局可用

二、把axios挂载到Vue原型上并配置请求根路径

(1) 因为我们希望axios 全局可用,所以需要在 main.js文件中进行相应配置,步骤如下:

  1. 导入 axios 模块
  2. 将 axios 挂载到 Vue 原型上。
import Vue from 'vue'
import App from './App.vue'

// 1.导入axios模块
import axios from 'axios'

Vue.config.productionTip = false

// 2.将axios挂载到Vue原型上
Vue.prototype.$http = axios

new Vue({
  render: h => h(App)
}).$mount('#app')

【注意】将axios挂载到Vue原型上时,其中$http的名字是任意的,表示我们在Vue原型上挂载了一个名为$http的属性(方法),它的值为axios。习惯上,我们都把这个属性命名为$http

(2) 为了简化.vue组件实例的调用,可以配置一个请求根路径,之后使用时只需要传入根路径之后的部分即可。

import Vue from 'vue'
import App from './App.vue'

// 1.导入axios模块
import axios from 'axios'

Vue.config.productionTip = false

// 3.配置请求根路径
axios.defaults.baseURL = 'http://www.liulongbin.top:3006'
// 2.将axios挂载到Vue原型上
Vue.prototype.$http = axios

new Vue({
  render: h => h(App)
}).$mount('#app')

(3)在组件中的使用方法:

  1. 不再需要导入axios模块,直接删除导入代码
  2. 每一个.vue组件都可以看成是一个Vue实例,因为Vue原型上挂载了一个名为$http的属性,而.vue组件又是一个Vue实例,所以可以通过this.$http拿到axios,然后就可以正常使用了。
  3. 由于配置了请求根路径,所以GET/POST请求的第一个参数,直接传入根路径之后的部分即可。

Left组件的script标签内容:

<script>
// 不再需要导入axios模块,直接删除导入代码
export default {
  data() {
    return {
      bookList: {}
    }
  },
  methods: {
    async getInfo() {
      const { data: res } = await this.$http.get('/api/getbooks')
      console.log(res)
      // 一般把请求回来的数据转存到data中
      this.bookList = res
    }
  }
}
script>

Right组件的script标签内容:

<script>
export default {
  methods: {
    async postInfo() {
      const { data: res } = await this.$http.post('/api/post', { name: 'zs', age: 20 })
      console.log(res)
      // 不再演示数据转存到data的过程
    }
  }
}
script>

【缺点】:请求数据的代码复用性差,如果不同的组件需要请求同一份数据,每请求一次,就要写一次请求函数。

三、封装一个拿到axios的模块,并封装请求数据的API

1.封装axios模块

在和src目录同级的地方,新建一个utils文件夹,表示用到的工具,在里面新建一个request.js文件,这个就是封装axios的模块。谁需要用到这个根路径去请求数据,谁就导入这个模块。

request.js文件的内容:

// 导入axios
import axios from 'axios'

// 通过axios.create方法创建一个axios实例,用request接收
const request = axios.create({
  // 指定请求的根路径
  baseURL: 'http://www.liulongbin.top:3006'
})

export default request

使用方法(以Left组件为例):

<script>
// 导入request模块
import request from '@/utils/request.js'

export default {
  data() {
    return {
      bookList: {}
    }
  },
  methods: {
    async getInfo() {
      // 假设需要传一个参数,这里的参数是假的,演示用
      const { data: res } = await request.get('/api/getbooks', {
        params: { id: 1 }
      })
      console.log(res)
      // 一般把请求回来的数据转存到data中
      this.bookList = res
    }
  }
}
script>

【拓展】一个项目中可以封装多个axios模块,如果需要用到多个不同的请求根路径,那么每一个根路径封装一个对应的axios模块,然后各模块之间互不相同,互不影响。

但是这个时候还是没有解决代码复用性低的问题,请求函数会重复写。此时我们再把请求数据的代码封装成一个API模块

2.封装API模块

在和src目录同级的地方,新建一个api文件夹,表示自己写的api,在里面新建一个bookAPI.js文件,这个就是封装的books的模块,关于book的所有API接口,都可以封装到这个模块。谁需要用到这个API接口,谁就导入这个模块。

bookAPI.js文件的内容:

// 导入request模块
import request from '@/utils/request.js'

// 向外按需导出一个接口函数
export const getBookListAPI = function() {
  // 记得一定要把请求到的promise对象return出去
  return request.get('/api/getbooks', {
    // 假设需要传一个参数,这里的参数是假的,演示用
    params: { id: 1 }
  })
}
<script>
// 按需导入bookAPI
import { getBookListAPI } from '@/api/bookAPI.js'

export default {
  data() {
    return {
      bookList: {}
    }
  },
  methods: {
    async getInfo() {
      // 调用getBookListAPI请求数据
      const { data: res } = await getBookListAPI()
      console.log(res)
      // 一般把请求回来的数据转存到data中
      this.bookList = res
    }
  }
}
script>

这就实现了请求数据接口的封装,提高了代码的复用性。

你可能感兴趣的:(Vue,vue)