第一部分:基础语法
为什么需要mock数据?
前端工程师搭建页面时,往往需要数据进行渲染。但是我们在学习时,是没有后端工程师配合的,也就拿不到后台数据接口。如果使用nodejs来自己搭建后台接口,会增加学习成本。所以需要mock数据,完成页面的开发。
有哪些方法可以mock数据呢?
- Mock.js
Mock.js介绍
Mock: 一种模拟后端接口的解决方案,能让我们提前调用模拟接口,完成前端开发。
官网地址: mockjs.com
Mock.js原理
Mock.js 生成随机数据,拦截 Ajax 请求
Mock.js优点
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.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模块中的数据。如果没有匹配的请求路径,才会去请求真实的后台服务器。
devServer:vue.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/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>
效果:
给Mock加开关
我们还希望,后台接口还没有开发出来时,使用Mock模拟的数据。当后台接口开发完成时,则使用真实的接口,不再使用Mock模拟的数据,此时该怎么办呢?
在项目根目录下,新建一个文件.env.development,它用来提供开发阶段的环境变量。
修改mock/index.js代码,先判断process.env.Mock的值,再决定是否导出接口处理函数即可。
这样,当后台接口开发完成后,只要修改.env.development文件中的Mock字段,就能方便地禁用Mock模拟的数据了。
代码:
.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来模拟接口,需要哪几步?
2. 如何控制Mock接口的开关?
第三部分:总结或问题
一些问题
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 导入