mock数据 - Mock.js篇

462 阅读7分钟

第一部分:基础语法

为什么需要mock数据?

前端工程师搭建页面时,往往需要数据进行渲染。但是我们在学习时,是没有后端工程师配合的,也就拿不到后台数据接口。如果使用nodejs来自己搭建后台接口,会增加学习成本。所以需要mock数据,完成页面的开发。

有哪些方法可以mock数据呢?

  • Mock.js

Mock.js介绍

Mock: 一种模拟后端接口的解决方案,能让我们提前调用模拟接口,完成前端开发。

官网地址: mockjs.com

Mock.js原理

Mock.js 生成随机数据,拦截 Ajax 请求

Mock.js优点

mockjs-1-20211204164223.png

Mock.js初体验

只需要以下简单的三个步骤,即可快速上手。

安装
npm install mockjs --save

导入
var Mock = require('mockjs')

使用
var data = Mock.mock({...})

Mock.js语法规范

1 . 数据模板定义规范 (Data Template Definition,DTD)
数据模板中的每个属性由3部分构成: 属性名(name)、生成规则(rule)、属性值(value):

    'name|rule':value

2 . 数据占位符定义规范 (Data Placeholder Definition,DPD )
占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中。

    @占位符
    @占位符(参数 [,参数])

数据模板定义规范

属性值是字符串String

1. 'name|min-max': string
通过重复string生成一个字符串,重复次数大于等于min,小于等于max。

2. 'namelcount': string
通过重复string 生成一个字符串,重复次数等于count。

属性值是数字Number

1. 'name|min-max': number
生成一个大于等于min、小于等于max的整数.属性值number只是用来确定类型。

示例1:生成一个用户名,值为一个字符串,长度在1-10。

//test.js
const Mock = require('mockjs')

var data = Mock.mock({
    'username|1-10': '*'
})

console.log(data)

通过nodejs执行test.js,输出如下:

 { username: '*******' }

示例2:生成一个年龄,值在1-100之间。

'age|1-100': 0

数据占位符定义规范

mock()方法 也可以传入一个占位符字符串,如'@cname()'。占位符后面的圆括号里可以传入参数。如果没有参数则可以省略圆括号,如'@id' 和 '@id()' 都行。

@id():得到随机的id
@cname():随机生成中文名字
@date('yyyy-MM-dd'):随机生成日期
@paragraph():描述
@email():邮箱地址

示例4:随机生成一个id。

const Mock = require('mockjs')
 
var data = Mock.mock('@id()')

console.log(data)
13000020120127608X

示例5:随机生成一个中文名。

var data = Mock.mock('@cname()')
戴秀英

案例练习:生成一个随机用户对象,结构如下所示:

{ 
    "id" : "230000201903033537""username" : "卢平""date" : "1978-09-16""description" : "Kcb jkkvdypcst xef .",
    "email" : "n.qoimyx@ewoea.mh""age" : 29
}

实现代码:

var data = Mock.mock({
    id: '@id()',
    username: '@cname()',
    date: '@date(yyyy-MM-dd)',
    description: '@paragraph()',
    email: '@email()',
    'age|18-60': 0
})

小结

1.Mock.js有什么作用?
一种模拟后端接口的解决方案,能让我们提前调用模拟接口,完成前端开发。

2.Mock.js的语法规范包括哪两部分?
数据模板和数据占位符

3.Mock.js基本代码格式

mock-2QQ截图20211204225830.png

第二部分:实战应用

Mock.js在Vue中的使用

问题: 我们如何在Vue项目中,使用Mock.js来模拟接口,并完成调用呢?

步骤:
1. 定义接口路由,在接口中并返回mock模拟的数据
2. 在vue.config.js中配置devServer,在before属性中引入接口路由函数
3. 使用axios调用该接口,获取数据

原理:

npm run serve 运行项目时, @vue/cli脚手架会根据 vue.config.js中配置的devServer字段,去启动一个使用express框架创建的后台服务器。当我们页面发起ajax请求时,会优先执行before函数,如果请求路径匹配,则使用Mockjs模块中的数据。如果没有匹配的请求路径,才会去请求真实的后台服务器。

devServervue.config.js中的一个可选配置项,如果配置了该字段,则运行项目时会启动一个后台服务器,使得在浏览器中能够通过url的方式来访问当前项目,方便查看项目效果。

Mockjs模块:通过编写express语法代码,为devServer提供路由地址和请求处理函数。

案例练习

1 通过@vue/cli创建一个新的Vue项目。
2 下载安装mockjs
3 编写Mock.js模块代码
为devServer提供接口路由函数
4 在vue.config.js中配置devServer,在before属性中引入步骤3中的接口路由函数
5 下载安装axios
6 在页面中使用axios,请求mockjs中的路由,获取mock数据。
7 编写完代码后,执行npm run serve,运行项目,查看效果。

业务需求:在页面中,点击搜索按钮,发起ajax请求,请求路径为/api/userinfo,拿到响应数据后,将用户信息渲染到页面上。

核心代码

项目目录: mock-3QQ截图20211205161503.png

mock/index.js

const Mock = require('mockjs')

//随机生成一个对象,表示一条个人信息
var data = Mock.mock({
	id: '@id()',
	username: '@cname()',
	date: '@date(yyyy-MM-dd)',
	description: '@paragraph()',
	email: '@email()',
	'age|18-60': 0
})

/*  
	/api/userinfo  请求路径
	req 请求对象
	res 响应对象
	json() 将对象转换为json字符串,响应给浏览器
*/
module.exports = function(app){
	//nodejs中的express框架
	//参数1: 接口地址; 参数2: 服务器处理函数
	app.use('/api/userinfo', (req, res) => {
		//将模拟的数据转成json格式返回给浏览器
		//res.json(data) 
		res.send(data)
	})
}

vue.config.js

module.exports = {
	devServer: {
		before: require('./src/mock/index.js')
	}
}

MockTest.vue

<template>
	<div class="mocktest">
		<div class="btn" @click="handleSearch">搜索</div>
		<div class="data">
			<p>搜索结果:</p>
			<div class="content" v-if=" typeof info === 'object'">
				<p>username: {{info.username}}</p>
				<p>id: {{info.id}}</p>
				<p>age: {{info.age}}</p>
				<p>date: {{info.date}}</p>
				<p>email: {{info.email}}</p>
				<p>description: {{info.description}}</p>
			</div>
			<div v-else>"暂无数据"</div>
		</div>
	</div>
</template>

<script>
	import axios from 'axios'
	
	export default {
		data(){
			return {
				info: '暂无数据'
			}
		},
		methods: {
			async handleSearch(){
				let { data: res } = await axios.get('/api/userinfo')
				this.info = res
				console.log(res)
			}
		}
	}
</script>

<style scoped="scoped">
	.btn {
		margin: 50px auto;
		display: flex;
		justify-content: center;
		align-items: center;
		width: 100px;
		height: 40px;
		color: #fff;
		background-color: #42B983;
		border-radius: 20px;
	}
	.btn:hover {
		background-color: #422983;
	}
	.data{
		width: 200px;
		margin: 0 auto;
	}
</style>

效果:

image.png

image.png

给Mock加开关

我们还希望,后台接口还没有开发出来时,使用Mock模拟的数据。当后台接口开发完成时,则使用真实的接口,不再使用Mock模拟的数据,此时该怎么办呢

在项目根目录下,新建一个文件.env.development,它用来提供开发阶段的环境变量

修改mock/index.js代码,先判断process.env.Mock的值,再决定是否导出接口处理函数即可。

这样,当后台接口开发完成后,只要修改.env.development文件中的Mock字段,就能方便地禁用Mock模拟的数据了。

代码

image.png

.env.development

//控制是否需要使用Mock模拟的数据
//需要使用Mock模拟的数据 则修改值为true。不需要,则修改值为false。
MOCK = false

mock/index.js

...

module.exports = function(app){
	//注意Mock变量会被解析成一个字符串
	if(process.env.Mock === 'true'){
		app.use('/api/userinfo', (req, res) => {
			//res.json(data) 
			res.send(data)
		})
	}
}

注意:
1.环境变量可以随意定义,但是它的值是字符串类型。
2.配置文件修改后,需要重新执行npm run serve来重新运行项目。

小结

1. 在Vue中使用Mock.js来模拟接口,需要哪几步?

image.png

2. 如何控制Mock接口的开关?

image.png

第三部分:总结或问题

一些问题

1.Commonjs模块不能在浏览器中直接使用。

Commonjs模块: 即使用了require()方法的js文件。

require() 是Commonjs的语法,只有Nodejs能够识别和解析。而浏览器不认识require(),所以如果html文件通过script标签引入包含require模块,则会报错。Uncaught ReferenceError: require is not defined

所以,不能简单地通过浏览器来执行Commonjs模块。

2.如何运行Commonjs模块化规范的js文件呢?方便查看mock数据的效果?

可以使用Nodejs来执行。在命令行窗口中执行: node xxx.js

Commonjs模块中,也可以使用console.log()方法 来打印mock出来的数据,方便查看效果。

3. 在编写mock/index.js时,为什么使用require()加载mockjs库,而不是使用import?

因为Mockjs一般需要配置devServer来使用,而devServer的配置文件vue.config.js只支持Commonjs模块化语法,不支持ES6模块化语法。

Commonjs模块化语法

  • require() 导入一个模块
  • module.exports 导出一个模块

ES6模块化语法

  • export 导出
  • import 导入

第四部分:学习资源

视频教程

官方文档