[TOC]
>[success] # Mock.js模拟Ajax响应
接下来学习如何使用 **Mock** 来 **模拟 ajax 响应数据** ,下面是 **Mock** 的一个浓缩版本的 [Mock简明文档](https://www.kancloud.cn/wangjiachong/vue_notes/2342377)
>[success] ## 响应模拟
平时我们开发时,有时有 **测试环境** ,用 **服务端接口** 来 **获取数据** 进行开发,那如果有时 **没有测试环境接口** 呢,或者说后端开发人员比较忙给我们提出接口的更改并未及时更改,影响我们的开发,此时我们使用 **Mock** 来响应 **Ajax** 请求,能够快速的帮我们进行开发。
我们之前在 **src/mock/index.js** 文件夹内创建过 **Mock** 的 **js** 文件,内容如下:
1. **创建 mock js 文件**
**src/mock/index.js**
~~~
import Mock from 'mockjs'
// 接口的数据都定义在中间
export default Mock
~~~
2. **在 main.js 中引入 mock 的 js 文件**
**src/main.js**
~~~
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'
import Bus from './lib/bus'
import Mock from './mock' // 引入mock
Vue.config.productionTip = false
Vue.prototype.$bus = Bus
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
~~~
上面是引入了我们创建的 **mock** 的 **js** 文件,我们希望 **生产环境** 不需要用 **mock** 来 **拦截我们的请求** ,只需要在开发环境上使用 **mock** ,此时我们可以进行一个判断,如下:
**src/main.js**
~~~
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'
import Bus from './lib/bus'
// 非生产环境时引入 mock
if(process.env.NODE_ENV !== 'production') require('./mock')
Vue.config.productionTip = false
Vue.prototype.$bus = Bus
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
~~~
2. **在实战中使用时**
在页面正常调用接口
**src/views/Home.vue**
~~~
<template>
<div>
<button @click="getInfo">请求数据</button>
</div>
</template>
<script>
import { getUserInfo } from '@/api/user'
export default {
methods: {
getInfo(){
getUserInfo({ userId: 21 }).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
}
}
}
</script>
~~~
接口文件:
**src/api/user.js**
~~~
import axios from './index'
// 获取用户信息接口
export const getUserInfo = ({ userId }) => {
return axios.request({
url: '/index/getUserInfo',
method: 'post',
data: {
userId
}
})
}
~~~
我们接下来在 **mock** 的 **js** 文件中拦截 **/getUserInfo** 这个接口,代码如下:
**src/mock/index.js**
~~~
import Mock from 'mockjs'
// 引入模拟数据接口
import { getUserInfo } from './response/user'
// 引入baseURL
import { baseURL } from '@/config'
/**
* 参数1是url,可以是字符串,可以是正则表达式,如果写字符串,需要把完整的url都写上
* 参数2是请求类型,也可以省略不写
* http://localhost:3000/index/getUserInfo 这块可以把baseUrl基础路径引入进来进行拼接,更方便一些
*/
Mock.mock(`${baseURL}/index/getUserInfo`, 'post', getUserInfo)
export default Mock
~~~
我们可以看到上面的代码中从当前文件夹中的 **response/user** 中引入了一个 **getUserInfo** 方法,这个方法就是通过 **mock** 模拟的数据,如下:
**src/mock/response/user.js**
~~~
/**
* 通过mock模拟getUserInfo接口数据
* @param {Object} options 请求体:body,请求类型:type,请求路径:url
*/
export const getUserInfo = (options) => {
return {
name: '小明'
}
}
~~~
请求后就可以在控制台看到打印结果:
![](https://img.kancloud.cn/e0/17/e0179cb6e3d31a6ee2b64afb1992d2ee_152x53.png)
>[success] ## Mock用法精讲
>[success] ### Mock.mock() 用法
**Mock.mock** 有 **3个参数** ,它们分别的用处是:
**参数1** 是 **url** 或 **正则表达式** 。上面我们使用的是 **url** 的方式,这里我们使用 **正则表达式** 的方式:
**src/mock/index.js**
~~~
import Mock from 'mockjs'
// 引入模拟数据接口
import { getUserInfo } from './response/user'
// 正则形式匹配url中有getUserInfo的接口
Mock.mock(/\/getUserInfo/, 'post', getUserInfo)
export default Mock
~~~
*****
**参数2** 是 **请求类型(get、post、put、delete等等)**
*****
**参数3** 是 **模板** 或 **方法** 。上面我们使用的是 **方法** 的方式,这里我们使用 **模板** 的方式:
**src/mock/index.js**
~~~
import Mock from 'mockjs'
// 模板的形式来模拟数据
Mock.mock(/\/getUserInfo/, 'post', {
name: '小明'
})
export default Mock
~~~
*****
还有更多 **Mock.mock** 写法,如下:
![](https://img.kancloud.cn/de/da/dedae70230a0fc718ec491afc8f56886_836x372.png)
>[success] ### 语法规范
**Mock 模拟出的数据** 是有 **数据模板** 的,由自己定义的规则来返回动态数据,具体规则可以参考 [Mock简明文档 > 语法规范 > 数据模板定义](https://www.kancloud.cn/wangjiachong/vue_notes/2342377#_20) 。
1. **使用数据模板**
首先在 **src/mock/response/user.js** 中引入 **Mock** ,然后再定义一个**数据模板** 的 **常量** 对象,在对象中使用**数据模板** ,最终 **return** 这个 **数据模板** ,代码如下:
**src/mock/response/user.js**
~~~
import Mock from 'mockjs'
/**
* 通过mock模拟getUserInfo接口数据
* @param {Object} options 请求体:body,请求类型:type,请求路径:url
*/
export const getUserInfo = (options) => {
// 在这里可以使用数据模板语法(属性名|生成规则:属性值)
const template = {
// --------------------------- 1.属性值是字符串 ------------------------------------
'str|2-4': '小明', // 重复生成一个字符串,重复次数大于等于 2,小于等于 4
'name|3': '小明', // 重复生成一个字符串,重复次数等于 3
// --------------------------- 2.属性值是数字 ------------------------------------
'age|+2': 18, // 属性值自动加 2,初始值为 18
'num|4-10': 0, // 生成一个大于等于 4、小于等于 10 的整数
'float|3-10.2-5': 0, // 生成一个浮点数,整数部分大于等于 3、小于等于 10,小数部分保留 2 到 5 位
// --------------------------- 3.属性值是布尔值 ------------------------------------
'bool|1': true, // 随机生成一个布尔值,值为 true 的概率是 1/2,值为 false 的概率同样是 1/2
'bool2|1-9': true, // 随机生成一个布尔值,值为 true 的概率是 10分之1(计算公式:1/(1+9)),值为 false 的概率是 10分之9(计算公式:9/(1 + 9)),公式:min / (min + max) 或 max / (min + max)
// --------------------------- 4.属性值是对象 ------------------------------------
'obj|2': { // 从属性值 object 中随机选取 2 个属性
a: 'aa',
b: 'bb',
c: 'cc',
},
'obj2|1-2': { // 从属性值 object 中随机选取 1 到 2 个属性
a: 'aa',
b: 'bb',
c: 'cc',
},
// --------------------------- 5.属性值是数组 ------------------------------------
'arr|1': [[1], [2], [3]], // 从属性值 array 中随机选取 1 个元素,作为最终值
'arr2|+1': [1, 2, 3, 4, 5, 6], // 从属性值 array 中顺序选取 1 个元素,作为最终值,用法与【数字属性值自动加 2】一样
'arr3|2-4': [1, 2, 3], // 通过重复属性值 array 生成一个新数组,重复次数大于等于 2,小于等于 4
'arr4|2': [1, 2, 3], // 通过重复属性值 array 生成一个新数组,重复次数为 2
// --------------------------- 6.属性值是函数 ------------------------------------
'func': () => { // 执行函数 function,取其返回值作为最终的属性值
return 'this is created by function'
},
// --------------------------- 7.属性值是正则表达式 ------------------------------------
'reg': /[1-9][a-z]/ // 1到9,a到z,根据正则表达式 regexp 反向生成可以匹配它的字符串。用于生成自定义格式的字符串
}
// 属性值是数字 属性值自动加 2的写法,如需用到,把此处注释解开,把下方return Mock.mock(template)注释掉
// let i = 3;
// let arr = []
// while(i--){
// arr.push(template)
// }
// return Mock.mock(arr)
// 传入模板(可以是对象或字符串)
return Mock.mock(template)
}
~~~
>[success] ### Mock.setUp() 用法
**Mock.setUp()** 可以传入一个配置项,对 **ajax** 进行设置,目前只支持配置 **timeout** ,配置方法如下,在 **src/mock/index.js** 文件中添加 **Mock.setUp()**
**src/mock/index.js**
~~~
import Mock from 'mockjs'
// 引入模拟数据接口
import { getUserInfo } from './response/user'
// 引入baseURL
import { baseURL } from '@/config'
/**
* 参数1是url,可以是字符串,可以是正则表达式,如果写字符串,需要把完整的url都写上
* 参数2是请求类型,也可以省略不写
* http://localhost:3000/index/getUserInfo 这块可以把baseUrl基础路径引入进来进行拼接,更方便一些
*/
Mock.mock(`${baseURL}/index/getUserInfo`, 'post', getUserInfo)
// 设置ajax配置
Mock.setup({
timeout: 500 // 500 毫秒
// timeout: '100-600' // 随机100-600 毫秒
})
export default Mock
~~~
>[success] ### Mock.Random用法
**Mock.Random** 里面包含了一些方法,我们来简单的看看如何使用:
1. **动态生成email**
**src/mock/response/user.js**
~~~
import Mock from 'mockjs'
// 引入Random 方法
const Random = Mock.Random
/**
* 通过mock模拟getUserInfo接口数据
* @param {Object} options 请求体:body,请求类型:type,请求路径:url
*/
export const getUserInfo = (options) => {
// 在这里可以使用数据模板语法(属性名|生成规则:属性值)
const template = {
email: Random.email() // 通过 Mock.Random 来动态随机生成邮箱
}
// 传入模板(可以是对象或字符串)
return Mock.mock(template)
}
~~~
或者也可以通过 **Mock.mock** 的 **@email 占位符** ,来动态生成 **email**
**src/mock/response/user.js**
~~~
import Mock from 'mockjs'
/**
* 通过mock模拟getUserInfo接口数据
* @param {Object} options 请求体:body,请求类型:type,请求路径:url
*/
export const getUserInfo = (options) => {
// 在这里可以使用数据模板语法(属性名|生成规则:属性值)
const template = {
email: Mock.mock('@email') // 通过 Mock.mock 传入占位符 @email 来动态生成 email
}
// 传入模板(可以是对象或字符串)
return Mock.mock(template)
}
~~~
**Mock.Random** 还有很多方法,其他方法可以查看 简明文档中的 **[Random 详细用法说明](https://www.kancloud.cn/wangjiachong/vue_notes/2342377#MockRandom_114)**
>[success] ### 扩展
我们可以自己 **扩展一些方法** ,而且还可以当做 **占位符** 使用,首先我们在 **src/mock/index.js** 文件中来自定义我们的一个 **fruit 水果的扩展方法**
1. **定义扩展方法**
**src/mock/index.js**
~~~
import Mock from 'mockjs'
// 引入模拟数据接口
import { getUserInfo } from './response/user'
// 引入baseURL
import { baseURL } from '@/config'
// 引用Random
const Random = Mock.Random
// 模拟getUserInfo接口数据
Mock.mock(`${baseURL}/index/getUserInfo`, 'post', getUserInfo)
// 设置ajax配置
Mock.setup({
timeout: 500 // 500 毫秒
})
// 扩展方法
Random.extend({
// 水果方法,随机返回一个水果
fruit () {
// 水果列表
const fruit = ['apple', 'peach', 'lemon']
return this.pick(fruit)
}
})
export default Mock
~~~
2. **使用扩展方法**
1. 通过 **Mock.mock** 传入 **占位符** 的方式使用
**src/mock/response/user.js**
~~~
import Mock from 'mockjs'
/**
* 通过mock模拟getUserInfo接口数据
* @param {Object} options 请求体:body,请求类型:type,请求路径:url
*/
export const getUserInfo = (options) => {
// 在这里可以使用数据模板语法(属性名|生成规则:属性值)
const template = {
fruit: Mock.mock('@fruit') // 通过自定义扩展的水果方法来生成数据
}
// 传入模板(可以是对象或字符串)
return Mock.mock(template)
}
~~~
2. **Mock.Random** 方式使用 **扩展方法**
**src/mock/response/user.js**
~~~
import Mock from 'mockjs'
// 引用Random
const Random = Mock.Random
/**
* 通过mock模拟getUserInfo接口数据
* @param {Object} options 请求体:body,请求类型:type,请求路径:url
*/
export const getUserInfo = (options) => {
// 在这里可以使用数据模板语法(属性名|生成规则:属性值)
const template = {
fruit: Random.fruit()
}
// 传入模板(可以是对象或字符串)
return Mock.mock(template)
}
~~~
- vue 26课
- Vue-cli3.0项目搭建
- Vue-ui 创建cli3.0项目
- Vue-ui 界面详解
- 项目目录详解
- public文件夹
- favicon.ico
- index.html
- src文件夹
- api文件夹
- assets文件夹
- components文件夹
- config文件夹
- directive文件夹
- lib文件夹
- mock文件夹
- mock简明文档
- router文件夹
- store文件夹
- views文件夹
- App.vue
- main.js
- .browserslistrc
- .editorconfig
- .eslintrc.js
- .gitignore
- babel.config.js
- package-lock.json
- package.json
- postcss.config.js
- README.en.md
- README.md
- vue.config.js
- Vue Router
- 路由详解(一)----基础篇
- 路由详解(二)----进阶篇
- Vuex
- Bus
- Vuex-基础-state&getter
- Vuex-基础-mutation&action/module
- Vuex-进阶
- Ajax请求
- 解决跨域问题
- 封装axios
- Mock.js模拟Ajax响应
- 组件封装
- 从数字渐变组件谈第三方JS库使用
- 从SplitPane组件谈Vue中如何【操作】DOM
- 渲染函数和JSX快速掌握
- 递归组件的使用
- 登陆/登出以及JWT认证
- 响应式布局
- 可收缩多级菜单的实现
- vue杂项
- vue递归组件
- vue-cli3.0多环境打包配置
- Vue+Canvas实现图片剪切
- vue3系统入门与项目实战
- Vue语法初探
- 初学编写 HelloWorld 和 Counter
- 编写字符串反转和内容隐藏功能
- 编写TodoList功能了解循环与双向绑定
- 组件概念初探,对 TodoList 进行组件代码拆分
- Vue基础语法
- Vue 中应用和组件的基础概念
- 理解 Vue 中的生命周期函数
- 常用模版语法讲解
- 数据,方法,计算属性和侦听器
- 样式绑定语法
- 条件渲染
- 列表循环渲染
- 事件绑定
- 表单中双向绑定指令的使用
- 探索组件的理念
- 组件的定义及复用性,局部组件和全局组件
- 组件间传值及传值校验
- 单向数据流的理解
- Non-Props 属性是什么
- 父子组件间如何通过事件进行通信
- 组件间双向绑定高级内容
- 使用匿名插槽和具名插槽解决组件内容传递问题
- 作用域插槽
- 动态组件和异步组件
- 基础语法知识点查缺补漏
- Vue 中的动画
- 使用 Vue 实现基础的 CSS 过渡与动画效果
- 使用 transition 标签实现单元素组件的过渡和动画效果
- 组件和元素切换动画的实现
- 列表动画
- 状态动画
- Vue 中的高级语法
- Mixin 混入的基础语法
- 开发实现 Vue 中的自定义指令
- Teleport 传送门功能
- 更加底层的 render 函数
- 插件的定义和使用
- 数据校验插件开发实例
- Composition API
- Setup 函数的使用
- ref,reactive 响应式引用的用法和原理
- toRef 以及 context 参数
- 使用 Composition API 开发TodoList
- computed方法生成计算属性
- watch 和 watchEffect 的使用和差异性
- 生命周期函数的新写法
- Provide,Inject,模版 Ref 的用法
- Vue 项目开发配套工具讲解
- VueCLI 的使用和单文件组件
- 使用单文件组件编写 TodoList
- Vue-Router 路由的理解和使用
- VueX 的语法详解
- CompositionAPI 中如何使用 VueX
- 使用 axios 发送ajax 请求
- Vue3.0(正式版) + TS
- 你好 Typescript: 进入类型的世界
- 什么是 Typescript
- 为什么要学习 Typescript
- 安装 Typescript
- 原始数据类型和 Any 类型
- 数组和元组
- Interface- 接口初探
- 函数
- 类型推论 联合类型和 类型断言
- class - 类 初次见面
- 类和接口 - 完美搭档
- 枚举(Enum)
- 泛型(Generics) 第一部分
- 泛型(Generics) 第二部分 - 约束泛型
- 泛型第三部分 - 泛型在类和接口中的使用
- 类型别名,字面量 和 交叉类型
- 声明文件
- 内置类型
- 总结