axios和mock
为什么把axios
和mock
放在一起呢?
因为在开发环境它们有时候需要配合使用,现代项目往往是前后端分离式的开发,前端和后端的主要联系在于接口的联调,前端往往需要依赖后端提供的接口返回的数据来编码页面逻辑。但因为分离式的开发,前端可能在需要某个接口的时候,这个接口后端还没有开发完成,无法调用。mock
便是为了应付这种场景,后端没数据没有关系,我前端自己造,后端提供接口文档说明接口规范,前端根据文档正常定义xmlhttp
请求,然后调用mock
拦截请求,返回mock
定义的数据,这样就实现了伪后端联调
的效果。
那么,这个过程如何实现呢?
不着急,我们先分别看看这两个插件的用法。
axios
官方文档见这里
axios
是一款基于Promise
的用于浏览器
和node.js
环境的http
请求插件。
现以常见的基于npm
和webpack
项目为例,来大概介绍下其使用方法:
- 首先安装
axios
插件,我这里用的yarn
,用npm
或者cnpm
之类的请自行切换对应的命名。
yarn add axios
- 统一请求配置和设置拦截器
在assets/js/
目录下新建http.js
文件,添加公共的请求配置和对应的request
和response
拦截器。
import axios from 'axios' const instance = axios.create({ timeout: 30000, headers: {} }); // 添加请求拦截器 instance.interceptors.request.use(function (config) { // 在发送请求之前做些什么,比如说这里统一调用loading遮罩层,给每个请求添加时间戳的参数 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 instance.interceptors.response.use(function (response) { // 对响应数据做点什么,比如说移除遮罩层,根据后端返回code判断是不是登录失效而统一配置跳到登录页 if(response.status === 200) return response.data; return Promise.reject(response); }, function (error) { // 对响应错误做点什么 return Promise.reject(error); }); export default instance;
- 使用
在main.js
或者vue
项目的store.js
中引入http.js
中实例化的axios对象instance
。
在import $http from '../http.js'
main.js
中,可以将$http
挂载到Vue
原型上,这样就可以直接在各组件中调用。
又或者直接在// 挂载到原型上后可通过this.$http来调用 Vue.prototype.$http = $http
store.js
(可以根据实际使用自由拆分再合并到store.js
)中引入,然后配置请求,在各组件中用dispatch
的方法调用。
经过上面这样的配置后,你可以在组件中这样调用:import Vue from 'vue' import Vuex from 'vuex' import http from '../http.js' Vue.use(Vuex) export default new Vuex.Store({ state: {}, mutations: {}, actions: { getWeatherInfo({commit},str){ // 获取城市天气,str为城市code,如深圳为101280601 return new Promise((resolve, reject) => { http({ method: 'get', url: `/api/weather/city/${str}`, // 该请求的ip为http://t.weather.sojson.com,有兴趣的可以试试,能够调通 }).then(rs => { if(rs.result === 'success') { resolve(rs) }else{ reject(rs) } }) }) }, }, modules: {} })
上面这种配置方式的好处是this.$store.dispatch('getWeatherInfo',101280601).then(rs => {/* ... */})
service
层和views
层的代码可以很好的解耦,后期某个接口若有改动,直接去store.js
修改相应请求的配置,而不用一个一个去搜索使用到了这个接口的每处代码然后一一修改。
mock
官方文档见这里
先搬个官网的使用说明:
# 安装
yarn add mockjs
// 使用 Mock
var Mock = require('mockjs')
var data = Mock.mock({
// 属性 list 的值是一个数组,其中含有 1 到 10 个元素
'list|1-10': [{
// 属性 id 是一个自增数,起始值为 1,每次增 1
'id|+1': 1
}]
})
// 输出结果
console.log(JSON.stringify(data, null, 4))
说实话,上面的代码是看懂了,但并没有什么用,因为光靠这个使用方法,我也不知道如何将它和axios
的请求联系起来。网上搜索许久,也不知道个个都是大神还是怎么回事,几乎都是复制粘贴的内容,而内容主体与官网说明没有多少出入,看完依旧很懵。
那么到底该怎么使用呢?浪里淘沙般的操作还是让我找到了一些有帮助的帖子,按照思路整了一番,终于找到一种能让自己满意使用mock.js
的模式了。
组合使用
我对mockjs
的期望一直是非侵入式拦截
,并且有个类似总开关的存在可以决定是否开启mockjs
。
那如何来使用mockjs
呢?
- 首先在某文件夹中新建
mock.js
文件,其内容大致如下:const MOCK = require('mockjs') MOCK.mock('/api/weather/city/101280601','get',{ status: 'error', msg: '天气查询失败' })
- 在
main.js
中require
加载mock.js
文件
这样你在某组件中调用这个天气查询接口,你if(process.env.NODE_ENV === 'development'){ // 区分环境,这样即使打包时忘了把下面代码注释掉也不会影响生产环境 require('../mock') // 不需要开启mock }
console.log
返回的内容会发现返回的是你自己定义的mock数据
,查看控制台的network
也会发现这个请求并没有被发送出去。但这个过程给人的体验与正常从后端接口获取数据无异。
所以这是什么情况呢?
原来,只要你的项目中有做require('mockjs')
这个动作,那么mockjs
便会拦截所有请求,不管你是否配置了某个接口应该返回什么样的假数据。这个你可以从network
中验证这一点。
那么,在实际开发过程中,为了正常使用mockjs
,我们在配置接口的时候都要做两份,一份是假设可以正常从后端获取数据的逻辑代码,一份是mock
定义的模拟数据代码。
mockjs
使用的基本方式如下:,
关于MOCK.mock(url,method,mockData) // api,方式,假数据
axios
和mockjs
一些细节方面的东西都可以参考官方文档。
网友评论