Vue
DAY10
封装Axios
当前业务中使用Axios
发送请求时的API
设计弊端:
-
每次发送请求,都需要写
url
的前缀,前缀一共有两种:生产环境下: https://web.codeboy.com/bmdapi/ https://web.codeboy.com/bmduploadapi/ 测试环境下: http://localhost:3010/ http://localhost:9000/
现阶段的写法如果需要切换生产环境与测试环境url前缀时,非常麻烦。
-
如果在项目有很多个地方需要发送相同类型的请求(例如:查询演员列表),那么每次发送查询演员列表请求时,都需要使用相应的url接口地址:
/movie-actors
。地址根本记不住,每次发请求,都得去接口文档中复制粘贴。更可恶的是,如果领导修改了接口地址,所有使用该地址的地方都需要改一遍。非常麻烦。
封装Axios
的目的就是解决请求资源路径难以维护的问题。
Axios
封装的设计流程
-
解决每次发请求都需要写请求地址的问题。
在http目录下新建index.js,导出httpApi对象,提供发各种业务请求的方法即可。
// 将常用的API请求发送业务,封装成方法,方便调用 import myaxios from "./MyAxios"; const httpApi = { /** 查询所有演员 */ queryAllActors() { let url = "http://localhost:3010/movie-actors"; let params = { page: 1, pagesize: 20 }; return myaxios.get(url, params); }, }; export default httpApi;
在使用时,直接调用业务方法即可完成相应业务:
import httpApi from '@/http/index' mounted () { httpApi.queryAllActors().then(res=>{ this.actors = res.data.data }) },
-
当解决了上述问题后,又发现
httpApi
对象中需要定义所有的请求接口方法,导致httpApi对象臃肿不堪,方法繁杂,所有接口的访问方法都在这一个对象里。需要按模块拆分。把相应的API方法放入单独的API模块文件中。新建
http/apis/ActorApi.js
,将演员相关接口搬进来:/** 该文件仅存放演员模块相关的接口API */ import myaxios from "../MyAxios"; const actorApi = { /** 查询所有演员 */ queryAll() { let url = "http://localhost:3010/movie-actors"; let params = { page: 1, pagesize: 20 }; return myaxios.get(url, params); }, } export default actorApi;
重构
index.js
,index.js
将作为这些子模块的入口,管理所有子模块的访问:// 当前模块整合所有的API子模块,方便调用 import actorApi from './apis/ActorApi' const httpApi = { actorApi, }; export default httpApi;
此时,访问接口的方法改为:
/** 组件挂载完毕后自动调用 生命周期方法 */ mounted () { httpApi.actorApi.queryAll().then(res=>{ this.actors = res.data.data },
接下来即可将所有
actor
相关的接口进行实现,重构代码。/** 该文件仅存放演员模块相关的接口API */ import myaxios from "../MyAxios"; const actorApi = { /** * 新增演员 * @param {Object} params {actorName:名字, actorAvatar:头像路径} */ add(params){ return myaxios.post( 'http://localhost:3010/movie-actor/add', params) }, /** * 通过姓名模糊查询演员列表 * @param {Object} params {name:姓名关键字} */ queryByNameLike(params){ return myaxios.post( 'http://localhost:3010/movie-actors/name', params) }, /** * 删除演员 * @param {Object} params {id:演员ID} */ delete(params){ return myaxios.post( 'http://localhost:3010/movie-actor/del', params) }, /** 查询所有演员 */ queryAll() { let url = "http://localhost:3010/movie-actors"; let params = { page: 1, pagesize: 100 }; return myaxios.get(url, params); }, } export default actorApi;
接口整理完毕后,以后每次在使用这些
API
时可以引入该模块,调用相应方法即可。import httpApi from '@/http/index' httpApi.actorApi.queryAll() httpApi.actorApi.queryByNameLike({name:'张'}) .....
但是,项目中的每一个组件页面都需要
import
,既然几乎所有的组件都需要使用httpApi
对象,那么完全可以将httpApi
对象设置为全局对象,放入Vue
实例中,方便使用。在每一个组件中使用this
即可访问全局的Vue
对象。/** 引入全局变量,方便组件调用模块API */ import httpApi from '@/http/index' Vue.prototype.$http = httpApi // 这样在组件中,可以使用如下方式调用接口 this.$http.actorApi.queryAll()
-
针对业务
API
子模块,封装请求路径的前缀,使得方便的更换项目中每个接口使用的服务端地址前缀。// 当前文件用于封装请求路径的前缀 // 两套环境:DEV: DEVELOPMENT 开发环境 // PRO: PRODUCTION 生产环境 const URLENV = { DEV: { // 封装开发环境下的路径前缀 BMDURL : 'http://localhost:3010', UPLOADURL : 'http://localhost:9000' }, PRO: { // 封装生产环境下的路径前缀 BMDURL : 'https://web.codeboy.com/bmdapi', UPLOADURL : 'https://web.codeboy.com/bmduploadapi' } } export default URLENV.DEV;
电影管理模块
整理左侧边栏导航及路由子页面
设计嵌套路由:
http://localhost:8080/home/movie-list 看到电影列表页
http://localhost:8080/home/movie-add 看到新增电影页
准备两个页面:views/movie/MovieList.vue
views/movie/MovieAdd.vue
配置嵌套路由,使之满足上述嵌套路由的设计。
搭建两个组件页面的静态内容。
实现电影页面挂载完毕后加载电影列表数据
业务需求:当点击菜单后,跳转到电影列表页,在电影列表页中显示电影列表数据。加载到数据后,以el-table
的方式显示在页面中即可。
实现步骤:
- 准备好发送电影相关请求的接口模块:
src/http/apis/MovieApi.js
。将该模块加入到src/http/index.js
中,供组件页面调用。 - 在电影列表页中,重写
mounted
生命周期方法,在该生命周期方法中,调用接口发送列表请求,获取电影列表数据后存入data
。 - 完成电影列表的渲染显示。显示在
<el-table :data="movies.result">
中。
实现电影列表数据的分页
首先需要添加ElementUI
提供的分页器。当用户点击了分页器中的页码时,获取选中的页码数字,重新发送请求,传递相应参数{page:xxx, pagesize:3}
,加载新的列表,呈现在表格中。
实现思路:
-
研究
<el-pagination>
组件的使用技巧。<el-pagination background layout="->, prev, pager, next, total, jumper" :current-page="1" :page-size="3" :total="1000" @current-change="pageChange"> </el-pagination>
-
发送请求,获取响应后,需要为
pagination
组件的属性动态赋值,这样就可以更新分页器效果。 -
绑定
current-change
事件,当前页更新后触发,发送新的请求即可。