【mock】后端不来过夜半,闲敲mock落灯花 (mockjs+Vuex+Vue实战)
目录
正文
mock 的由来【假】
赵师秀:南宋时期的一位前端工程师
诗词背景:在一个梅雨纷纷的夜晚,正处于项目编码阶段,书童却带来消息:写后端的李秀才在几个时辰前就赶往临安度假去了,!此时手头仅有一个简单的数据接口文档的赵师秀慨叹一声:"好吧,那还是我自己先模拟一下后端的接口吧"
_(:3 」∠)_ 再后来,就有了那句千古名句啦~~( 为了表示对赵师秀先生的歉意,文末我将附上原文)
如果我说这就是前后端分离思想和 mock.js 的由来,你会信么?(ฅ´ω`ฅ)
mock 的由来【真】
我们在 Vue 或 React 的文档里时不时就会看到这个名词,那么 mock 到底是什么东西呢?
mock 有“愚弄、欺骗”之意,在前端领域,mock 可以理解为我们前端开发人员制造的假数据。也就是说不是由后台真实制造,而是由我们其他一些方式模拟的数据,例如借助 mock.js。
通过这种方式,我们能在一定程度上实现前后端分离的开发流程。因为如果前端开发人员能够自己模拟数据的话,就不必等着拿到后端的接口才能完成剩下的工作,使得前端人员独立开发的能力增强,在此基础上做到前端后台各自独立的开发(当然这个前提是有写好详细地公共数据接口的文档)
最后对接的工作是前后端联调数据,因为前端 mock 的辅助,我们尽可能地减少了前后端对接过程中的效率损耗
mock.js 初上手——安装和使用
在终端里通过运行 npm install mockjs 去安装 mock.js 模块,安装成功后你就可以通过模块化的方式去使用模块化的方式去使用 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))
demo:
mock.js 抢鲜看——主要的作用和 API
mock.js 的作用![]()
mock.js 的作用,从它文档的首页介绍便可以略知一二:
1.它可以生成大量不同类型的模板数据,从最基本的随机数组 / 数字 / 对象 / 字符串,再到一个域名,一个地址(省 / 市),一个标题,一段文字,甚至给定宽高和颜色的图片,它都能模拟生成! 这就是 mock.js 的强大之处
2. 相比起生成随机的模拟数据,其实我们更关心的是当我们发送 Ajax 请求的时候,我们能够接收到这些数据,这就是 mock.js 的第二大作用:拦截 Ajax 请求,当你对一个 mock.js 所指定的 URL 发起 Ajax 请求的时候,mock.js 会将 1 中的模板数据作为响应数据回传给你,从而让你开发能在相当于已经拿到后端接口的前提下进行前端开发!
【注意】:mock.js 只拦截 Ajax,而不是 fetch,所以, 习惯于使用 fetch 的 API 的朋友们要注意了
mock 的 API 其实非常简单,主要要用到的 API 其实就两个(我是说主要哈 ~~):
1.Mock.Random
这是一个对象,对象里包含许多可供调用的方法,返回相应的模拟数据,例如 Mock.Random.domain()可以返回一个随机的域名,Mock.Random.csentence() 可以返回一个随机的中文句子
2.Mock.mock([你发起 Ajax 请求的 URL], ["get" 或 "post"],[根据 Mock.Random 定制的模板或函数])
调用这个方法后你就可以发起 Ajax 请求并且接收到你私人定制的随机数据啦!
【注意】前两个参数是字符串,最后一个参数是对象或函数
所以下面我就主要围绕这两点展开
Mock.Random 的运用
模拟 Web 数据:
生成随机域名 (每次运行结果不同):
var Random = Mock.Random Random.domain() // "nhou.org.cn"
生成随机 IP(每次运行结果不同)
var Random = Mock.Random Random.ip() // "74.97.41.159"
生成随机 URL(每次运行结果不同)
Random.url() // "news://wrmt.na/rbcgbws"
模拟地理位置数据:
生成随机省份:
var Random = Mock.Random Random.province() //"海南省"
生成随机城市:
var Random = Mock.Random Random.city() // "澳门半岛"
生成在某个省份的某个城市:
var Random = Mock.Random Random.city(true) // "广东省 广州市"
模拟文本数据:
生成一条随机的中文句子:
var Random = Mock.Random Random.csentence() // "会候权以解包党心要按总场火义国而片精。"
【注意】
1. 默认一条句子里的汉字个数在 12 和 18 之间
2. 通过 Random.csentence(length) 指定句子的汉字个数:
Random.csentence(5) // "文斗领拉米。"
3. 通过 Random.csentence(min?, max?) 指定句子汉字个数的范围:
Random.csentence(3, 5) // "住验住"
生成随机的中文段落:
var Random = Mock.Random Random.cparagraph() // "电力速率离老五准东其引是外适只王。体区先手天里己车发很指一照委争本。究利天易里根干铁多而提造干下志维。级素一门件一压路低表且太马。"
【注意】
1. cparagraph 可以看作是多条 csentence 以逗号连接后的字符串,默认条数为 3 到 7 条 csentence
2. 通过 Random.cparagraph(length) 指定句子的个数
Random.cparagraph(2)
// "而易除应精基还主局按选际复格从导。天第们国分比积造业王该回过白亲。"
3. 通过 Random.cparagraph(min?, max?)指定句子的个数的范围:
Random.cparagraph(1, 3)
// "作养装军头确应当号天革来人车号把文。证细专物转民相解状律极或经较把马。其省级支际标业强龙算建物况。"
模拟颜色数据:
var Random = Mock.Random Random.rgba() // "rgba(122, 121, 242, 0.13)"
模拟日期 / 时间数据:
日期:
Random.date('yyyy-MM-dd') // "1975-04-27" Random.date('yy-MM-dd') // "00-01-08"
时间:
Random.time() // "05:06:06"
模拟图片:
Random.image('200x100', '#4A7BF7', 'Hello')
不指定参数则取随机的宽高并显示对应的宽高数据:
模拟姓名数据:
模拟全名:
Random.cname() // "黄秀英"
模拟姓氏:
Random.cfirst() // "龙"
模拟名字
Random.clast() // "秀英"
Mock.mock() 的运用
除了制造模拟数据之外,更关键的是,我们发起 Ajax 请求的时候要能够接收到这些数据呀。嘿嘿,这就是 Mock.mock() 的作用啦!
上面我介绍过 Mock.mock() 的用法,如下:
Mock.mock([你发起 Ajax 请求的 URL], ["get" 或 "post"],[根据 Mock.Random 定制的模板或函数])
在文章开头的时候,我们通过使用 mock 函数的第三个参数生成了对应的模拟数据:
var data = Mock([模板参数]);
但如果我们希望这个数据能够被请求某个URL的ajax接收到,那就要运用到前两个参数了:
用例如下:
[注意] 为了在Vue中使用Ajax,我注册了一个插件:Vue-Resource,关于更多可以参考Vue-Resource的官方文档:https://github.com/pagekit/vue-resource/blob/develop/docs/config.md
import Vue from 'vue' //注册Vue-Resource插件,这样我们就可以 Vue.http.get(URL)去发出Ajax请求了 import VueResource from 'vue-resource' Vue.use(VueResource) var Mock = require('mockjs') Mock.mock('/penghuwan.com/', 'get', { // 属性 list 的值是一个数组,其中含有 1 到 10 个元素 'list|1-10': [{ // 属性 id 是一个自增数,起始值为 1,每次增 1 'id|+1': 1 }] }) // 输出结果 Vue.http.get('/penghuwan.com/').then( response => { console.log(response.body) } )
demo:
Mock.js 小练兵——用 Vue + Vuex + mockjs 搭建一个简单的文章 Feed
下面,我将用用 Vue + Vuex + mockjs 搭建一个简单的应用,展示前后端分离的工作流程
先看看我们最终要达到的效果,这是 UI 的最小单元:
我们希望能显示多个文章卡片,并且向其中插入 mockjs 模拟的内容
我的主要文件有四个:
├── app.vue // 页面 UI
├── main.js // 入口文件,初始化 vuex 和 vue-resource, 并挂载 mockjs
├── mock.js // 生成模拟数据
└── module.js // vuex 的 module 部分
app.vue:
<template> <div id="app"> <template v-for ="(item, index) in articles"> <div :key="index"> <h1 class="title">{{item.title}}</h1> <div> {{item.content}} </div> <div> <p class="time">{{'发表时间:' + item.time}}</p> <p class="location">{{'发表地址:' + item.location}}</p> </div> </div> </template> </div> </template> <script> import {mapGetters, mapActions} from 'vuex' export default { mounted: function () { this.fetchData() }, methods: { ...mapActions({ fetchData: 'fetchArticlesData' }) }, computed: { ...mapGetters({ articles: 'getArticles' }) } } </script> <style scoped> #app div{ border: 1px solid gray; padding: 10px; margin: 10px; overflow: hidden; } #app p{ margin: 0px; } .title{ font-size: 16px; } .time{ float: left; } .location{ float: right; } </style>
入口文件 main.js:
import Vue from 'vue' import Vuex from 'vuex' import VueResource from 'vue-resource' import App from './app' import article from './module.js' Vue.use(Vuex) Vue.use(VueResource) // 调用 mock 的 API,使 Ajax 能够捕获随机数据 require('./mock.js') // 创建 Vuex 的 store const store = new Vuex.Store({ modules: { article } }) new Vue({ el: '#app', template: '<App />', store: store, components: {App} })
mock.js:
var Mock = require('mockjs') var Random = Mock.Random const produceData = function () { let articles = [] for (let i = 0; i < 10; i++) { let newArticleObject = { title: Random.csentence(5), content: Random.cparagraph(5, 7), time: Random.date() + ' ' + Random.time(), location: Random.city() } articles.push(newArticleObject) } return { articles: articles } } // 第三个参数可以是对象也可以是返回对象的函数 Mock.mock('/article', 'get', produceData)
module.js:
import Vue from 'vue' const RESQUEST_ARTICLES = 'RESQUEST_ARTICLES' export default { state: { articles: [] }, getters: { getArticles: state => state.articles }, actions: { fetchArticlesData (context) { context.commit(RESQUEST_ARTICLES) } }, mutations: { [RESQUEST_ARTICLES] (state) { Vue.http.get('/article').then( response => { let data = response.body state.articles = data.articles } ) } } }
demo:
再刷新一次看看!!:
【完】
黄梅时节家家雨,青草池塘处处蛙。有约不来过夜半,闲敲棋子落灯花
参考资料:
1.mock.js 官方文档: http://mockjs.com/
2.vue-resource 官方文档: https://github.com/pagekit/vue-resource
3.vuex 中文文档: https://vuex.vuejs.org/zh-cn/