MockJs
一、为什么使用mockjs
在做开发时,当后端的接口还未完成,前端为了不影响工作效率,手动模拟后端接口。
1.我们可以使用 json文件来模拟后台数据,但比较局限, 无法模拟数据的增删改查2.使用json-server模拟,但不能随机生成所需数据
3.使用mockjs模拟后端接口,可随机生成所需数据,可模拟对数据的增删改查
二、mock优点
1.前后端分离2.可随机生成大量的数据
3.用法简单
4.数据类型丰富
5.可扩展数据类型
6.在已有接口文档的情况下,我们可以直接按照接口文档来开发,将相应的字段写好,在接口完成 之后,只需要改变url地址即可。
官网地址: http://mockjs.com/github地址:https://github.com/nuysoft/Mock/wiki/Getting-Started
三、mockjs语法及使用
1、使用mockjs
项目安装mockjs
# 安装
npm install mockjs
项目中新建mock文件
//引入mock模块
import Mock from 'mockjs'
将mock文件在main.js中导入
import Vue from 'vue'
import App FROM './App.vue'
import './mock/index.js'
Vue.config.productionTip = false
new Vue({
render:h => h(App),
}).$mount('#app')
2、mock语法
生成字符串
- 生成指定次数字符串
import Mock from 'mockjs'
const data = Mock.mock({
"string|4":"你好!"
})
- 生成指定范围长度字符串
const data = Mock.mock({
"string|1-8":"你好!"
})
生成文本
- 生成一个随机字符串
const data = Mock.mock({
"string":"@cword"
})
- 生成指定长度和范围
const data = Mock.mock({
string:"@cword(1)",
str :"@cword(10,15)"
})
生成标题和句子
- 生成标题和句子
const data = Mock.mock({
title:"@ctitle(8)"
sentence:"@csentence"
})
- 生成指定长度的标题和句子
const data = Mock.mock({
title:"@ctitle(8)"
sentence:"@csentence(50)"
})
- 生成指定范围的
const data = Mock.mock({
title:"@ctitle(5,8)"
sentence:"@csentence(50,100)"
})
在这里你会发现这里的都是以c
开头的,如果不以c开头生成的就是英文的!
生成段落
- 随机生成段落
const data = Mock.mock({
content:"@cparagraph()"
})
生成数字
- 生成指定数字
const data = Mock.mock({
"number|80":1
})
- 生成范围数字
const data = Mock.mock({
"number|1-99":1
})
生成自增id
- 随机生成标识
const data = Mock.mock({
id:"@increment"
})
生成姓名-地址-身份证
- 随机生成姓名-地址-身份证
const data = Mock.mock({
name: "@cname()",
idCard: "@id()",
address: "@city(true)"
})
随机生成图片
- 生成图片:
img_url: "@image('300*200','#FFA07A','#FFBBFF','png','yykk')"
- 参数1:图片大小
[
'300*250','250*250','240*400','336*280',
'180*150','720*300','468*60','234*60',
'388*31','250*250','240*400','120*40',
'125*125','250*250','240*400','336*280'
]
- 参数2:图片背景色
- 参数3:图片前景色
- 参数4:图片格式
- 参数5:图片文字
生成时间
- @Date
- 生成指定格式时间:@date(yyyy-MM-dd hh:mm:ss)
指定数组返回的参数
- 指定长度:‘date|5’
- 指定范围:'data|5-10'
const data = Mock.mock({
'list|50-99':[
{
name:'@cname',
address:'@city(true)',
id:'@increment()'
}
]
})
3、mock拦截请求
定义get请求
Mock.mock('api/get/news','get',()=>{
return{
status:200,
message:"获取数据成功"
}
})
定义post请求
Mock.mock('api/post/news','post',()=>{
return{
status:200,
message:"获取数据成功"
}
})
4、实现新闻管理案例
获取数据
接口地址::/api/get/news
接口参数:
pageindex:页码
pagesize:每页的条数
请求类型:get
返回的数据:
{
status:200,
message:"获取新闻列表成功",
list:[
{
"id":1,
"title":"解忧杂货店",
"content":"《解忧杂货店》是日本作家东野圭吾写作的长篇小说。2011年《小说野性时代》连载,于2012年3月由角川书店发行单行本",
"img_url":"http://t15.baidu.com/it/u=2090705107,20534764&fm=224&app=112&f=JPEG?w=500&h=500&s=61D0718656561FFFE504A51703000067",
"add_time":"1984-04-03 11:43:37"}
],
total:50
}
}
添加新闻
接口地址::/api/add/news
接口参数:
title:'标题'
content:内容
请求类型:post
返回的数据:
{
status:200,
message:"获取新闻列表成功",
list:[
{
"id":1,
"title":"解忧杂货店",
"content":"《解忧杂货店》是日本作家东野圭吾写作的长篇小说。2011年《小说野性时代》连载,于2012年3月由角川书店发行单行本",
"img_url":"http://t15.baidu.com/it/u=2090705107,20534764&fm=224&app=112&f=JPEG?w=500&h=500&s=61D0718656561FFFE504A51703000067",
"add_time":"1984-04-03 11:43:37"}
],
total:50
}
}
删除新闻
接口地址::/api/delete/news
接口参数:
id;新闻id
请求类型:post
返回的数据:
{
status:200,
message:"获取新闻列表成功",
list:[
{
"id":1,
"title":"解忧杂货店",
"content":"《解忧杂货店》是日本作家东野圭吾写作的长篇小说。2011年《小说野性时代》连载,于2012年3月由角川书店发行单行本",
"img_url":"http://t15.baidu.com/it/u=2090705107,20534764&fm=224&app=112&f=JPEG?w=500&h=500&s=61D0718656561FFFE504A51703000067",
"add_time":"1984-04-03 11:43:37"}
],
total:50
}
}
接口名称相同,现在只是mockjs拦截了请求,只要上线的时候把mock注释,调用服务器接口,测试一下即可。防止后端返回数据不完善或者字段有遗漏
完整案例
mock/index.js
// 引入mockjs
import Mock from "mockjs";
const { newsList } = Mock.mock({
"newsList|75": [{
id: "@increment",
title: "@ctitle()",
content: "@cparagraph(5,10)",
img_url: "@image('50*50','#FF83FA','#FCFCFC','png','mono')",
add_time: "@date(yyyy-MM-dd hh:mm:ss)",
}, ],
});
console.log(newsList);
var getQuery = (url, name) => {
console.log(url, name);
const index = url.indexOf("?");
if (index !== -1) {
const queryStrArr = url.substr(index + 1).split("&");
for (var i = 0; i < queryStrArr.length; i++) {
const itemArr = queryStrArr[i].split("=");
console.log(itemArr);
if (itemArr[0] === name) {
return itemArr[1];
}
}
}
return null;
};
// 定义获取新闻列表的数据
// /api/get/news?pageinde1&pagesize=10
Mock.mock(/\/api\/get\/news/, "get", (options) => {
// 获取传递参数pageindex,pagesize
const pageindex = getQuery(options.url, "pageindex");
const pagesize = getQuery(options.url, "pagesize");
console.log(pageindex);
console.log(pagesize);
const start = (pageindex - 1) * pagesize;
const end = pagesize * pageindex;
const totalPage = Math.ceil(newsList.length / pagesize);
// pageindex:1 pagesize:10 返回0-9条数据 2-10-(10-19) 3-10(20-29)
// 数据的起始位置:(pageindex-1)*pagesize 结束位置:pageindex*pagesize
const list = pageindex > totalPage ? [] : newsList.slice(start, end);
return {
status: 200,
message: "获取新闻列表成功",
list: list,
total: totalPage,
};
});
// 定义添加新闻的数据
Mock.mock("/api/add/news", "post", (options) => {
const body = JSON.parse(options.body);
console.log(body);
newsList.push(
Mock.mock({
id: "@increment",
title: body.title,
content: body.content,
img_url: "@image('50*50','#FF83FA','#FCFCFC','png','mono')",
add_time: "@date(yyyy-MM-dd hh:mm:ss)",
})
);
return {
status: 200,
message: "添加成功",
list: newsList,
total: newsList.length,
};
});
// 定义删除新闻
Mock.mock("/api/delete/news", "post", (options) => {
console.log(options);
const body = JSON.parse(options.body);
console.log(body);
const index = newsList.findIndex((item) => {
return item.id === body.id;
});
newsList.splice(index, 1);
console.log(index);
return {
status: 200,
message: "添加成功",
list: newsList,
total: newsList.length,
};
});
console.log(Mock);
App.vue
<template>
<div>
<!-- 搜索 -->
<div class="add">
<input type="text" v-model="title" placeholder="输入标题" />
<input type="text" v-model="content" placeholder="输入内容" />
<button @click="add">添加</button>
</div>
<!-- 表格-->
<div class="news_list">
<table>
<tr>
<th>图片</th>
<th>标题</th>
<th>内容</th>
<th>时间</th>
<th>操作</th>
</tr>
<tr v-for="item in list" :key="item.id">
<td><img :src="item.img_url" alt="" /></td>
<td>{{ item.title }}</td>
<td>{{ item.content }}</td>
<td>{{ item.add_time }}</td>
<td><button class="remove" @click="remove(item.id)">删除</button></td>
</tr>
</table>
</div>
<!-- 上下页 -->
<div class="pages">
<button @click="prevPage">上一页</button>
<button @click="nextPage">下一页</button>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
title: '',
content: '',
list: [],
pageindex: 1,
title: '',
content: ''
}
},
methods: {
add() {
// if (this.title.trim() === "" || this.content.trim() === "")
// return alert("请添加那些新闻标题和内容");
// console.log(this.title, this.content);
axios
.post('/api/add/news', {
title: this.title,
content: this.content
})
.then((res) => {
console.log(res)
})
},
//获取新闻列表数据
getNewsList() {
axios
.get('/api/get/news', {
params: {
pageindex: this.pageindex,
pagesize: 10
}
})
.then((res) => {
console.log(res)
this.list = res.data.list
})
},
nextPage() {
this.pageindex++
this.getNewsList()
},
prevPage() {
this.pageindex--
this.getNewsList()
},
// 删除新闻
remove(id) {
// console.log(id);
axios
.post('/api/delete/news', {
id
})
.then((res) => {
console.log(res)
})
}
},
created() {
this.getNewsList()
},
mounted() {}
}
</script>
<style>
.add input {
border-radius: 5px;
border: none;
outline: none;
border: 1px solid #999;
padding: 5px;
margin-right: 5px;
}
button {
width: 100px;
height: 30px;
background: #409eff;
color: none;
outline: none;
border-radius: 5px;
margin-left: 5px;
cursor: pointer;
border: 0;
color: #fff;
}
.news_list {
width: 1220px;
height: 495px;
overflow-y: scroll;
overflow-x: hidden;
margin: 10px;
}
table {
border-collapse: collapse;
height: 495px;
overflow-y: scroll;
overflow-x: hidden;
margin: 10px;
border: 1px solid rgb(94, 92, 92);
}
table th {
font-size: 16px;
height: 30px;
width: 224px;
font-weight: normal;
border: 1px solid rgb(94, 92, 92);
}
table td {
font-size: 12px;
padding: 5px;
border: 1px solid rgb(94, 92, 92);
}
table td:nth-child(4) {
width: 150px;
}
table td:nth-child(2) {
min-width: 100px;
}
table img {
width: 80px;
height: 80px;
}
table .remove {
background: #f56c6c;
}
</style>