vue中使用mockjs模拟后台数据
阅读原文时间:2021年04月20日阅读:1

概述

以前的web开发中,前后端是紧密耦合在一起的,脱离了后端的前端几乎无法测试。两者的过度依赖不仅大大地提高了团队的沟通成本,还严重拖慢了项目的开发进度,非常不利于web项目的开发。于是前后端分离逐渐成为一种广为认可的开发模式。但在实际的web开发中,前后端的进度是很难做到实时同步的,因此经常会出现前端无接口可调的情况,这样前端开发很容易陷入阶段性停滞的泥潭。

为了将前后端进一步解耦,前端出现了一个数据模拟神器 - mockjs。它的作用就是以较低的成本模拟后端返回数据,从而使前端对后端开发进度的依赖进一步降低。下面我们一起看一下,在vue中是如何使用mockjs的。

vue中mockjs的使用流程

1. 安装mock

使用以下语句可以在vue中安装mockjs插件:

//--save-dev表示安装到开发依赖中,打包上线后将自动移除
npm install mockjs --save-dev

npm的安装这里不再详述。上面的语句就在当前项目的node_modules中安装了mockjs插件,并且经过webpack打包后,mockjs将自动从项目中移除。

2. 创建mock文件

你可以在项目的src目录下新建一个mock文件夹,用于保存所有的mock文件:

src
  |_ components
  |_ router
  |_ store
  |_ mock
     |_ login
        |_ login.js
     |_ message
        |_ message.js
     |_ index.js
  |_ App.vue
  |_ main.js

如图所示,mock文件夹用于存放所有的mock文件。为了方便管理,可以将文件继续分类,如上图继续分出了登录类(login)和消息类(message)。然后在mock目录下新建index.js,用于向外部提供统一的访问入口。下面我们在login下新建了一个login.js,它将用于拦截前端发送的登陆请求,模拟登录功能,而message下的message.js用于返回消息。

我们来看一下index.js和login.js的结构:
index.js:

//引入mockjs
import Mock from 'mockjs';
//导入login.js和message.js,这样只需导入index.js,
//即可使用这两个mock文件
require('./login/login.js');
require('./message/message.js');
//启动mock,timeout表示模拟的请求延迟
Mock.setup({
  timeout: 0-500,
})

上述timeout参数用于配置mock延迟。在实际的web请求中,前后端的数据响应总是有延迟的,而且这个延迟在某些情况下有可能影响到代码逻辑,但是用mock模拟数据时如果不设置延迟,请求几乎是立即返回的(因为我们是本地开发,访问的是本地mock)。为了更真实地还原web请求过程,我们人为地给请求设置了0-500毫秒的延迟(也可以写一个固定的整数,表示固定的延迟,单位毫秒)。

login.js

import Mock from 'mockjs';

let userSet = [
  { username: 'carter', password: '123' },
  { username: 'xishanyu', password: '456' },
]
//用mock模拟一个'/userlogin/login'的post请求,请求参数从req.body得到
Mock.mock('/userLogin/login', 'post', ( req ) => {
  //解析请求体,前端传的可能是JSON字符串
  let body = JSON.parse(req.body);
  let username = body.username;
  let password = body.password;
  //遍历模拟数据,检查该用户是否存在,并比对密码
  for(let user of userSet){
    if(user.username === username){
      if(user.password !== password){
        return 'password error';
      } else {
        return 'success';
      }
    }
  }
  //用户不存在
  return 'user not exist';
})

以上就写了一个简单的处理登录的模拟接口。下面我们来看如何调用这个接口。

3. 在前端代码中使用mock

我们要做的就是在项目的main.js中引入mock中的index.js,即:

...
import Mock from './mock/index.js';
...

现在我们就可以在任意一个组件中调用上述接口了。比如我们使用axios来调用上述接口:

//将对象字符串化可以压缩body的体积,但这不是必须的
this.$axios.post('/userLogin/login', 
  JSON.stringify({username: this.username, password: this.password}))
  .then( res => {
    if(res.data === 'password error'){
      //使用的是element-ui的message组件
      this.$message({
        message: '密码错误!',
        type: 'error'
      })
    } else if(res.data === 'user not exist'){
      this.$message({
        message: '用户不存在!',
        type: 'error'
      })
    } else {
      //登陆成功
      ...
    }
  }).catch( err => {
    //请求异常
    console.log(err);
  })

上面我们就调用了mock中的请求实现了登录功能。只要这里的接口是严格定义过的,而mock也是严格按照接口定义来返回数据的,那么在实际上线时,这里不需要做任何修改就可以和后端无缝衔接。

mock能做什么?

使用mock我们可以模拟各类请求,如post、get、delete、put等,上面的例子写了一个post接口,下面我们来实现一个常见的get接口:
message.js

import Mock from 'mockjs';
//mock中用于生成随机数据的类
const Random = Mock.Random;
/* 传入url和要解析出的参数名,解析查询参数 */
function getParameter(req, parameter){
  var parameters = req.url.split('?')[1];
  if(parameters){
    var results = parameters.split('&');
    for(let i = 0; i < results.length; i++){
      var result = results[i].split('=');
      if(result[0] === parameter){
        return result[1];
      }
    }
    return null;
  } else {
    return null;
  }
}

Mock.mock(RegExp('/message/getMessage' + '.*'), 'get', (req) => {
  let type = getParameter(req.url, 'type');
  if(type === 'unread'){
    //控制一次产生的消息数量为1 - 5条
    let num = Random.interger(1, 5); 
    let msg= [];
    for(let i = 0; i < num; i++){
      msg.push({
        //生成随机中文标题
        title: Random.ctitle(),
        //生成随机中文名
        name: Random.cname(),
        //生成随机日期
        date: Random.date(),
      })
    }
    return msg;
  } else {
    //生成其他类型的消息
    ...
  }
})

现在在前端即可调用该接口,每次请求将返回1-5条消息,消息的内容随机生成(生成的标题往往是一堆汉字的随机组合)。路径中使用了正则表达式的形式,是为了匹配所有带有任意查询参数的’/message/getMessage’请求,否则必须url严格匹配才能正确处理。

现在在前端只需要发送一个常见的get请求即可:

this.$axios.get('/message/getMessage?type=unread')
  .then( res => {
    console.log(res.data);
  })
  .catch( err => {
    console.log(err);
  })

mock能模拟哪些数据?

1. 基本类型数据

boolean(布尔类型)、
natural(自然数)、
interger(整数)、
float(浮点数)、
character(字符)、
string(字符串)、
range(范围)、
date、time、datetime、now(日期相关)。
他们全部属于Random类的静态方法,使用Random.interger(0, 10)的形式调用,具体的API请参考mockjs网站:mockjs使用文档

2. 图片

使用mockjs还可以模拟生成一张图片,并且可以规定图片的宽高、字体颜色、背景色和文本信息,默认生成的图片可能如下:

实际上这里返回的只是一个url(如 https://dummyimage.com/720x300 ),我们使用的实际上是mockjs提供的网络图片。另外还可以生成编码过的图片,将生成的字符串直接作为img标签的src即可显示(如需进一步了解,请自行查阅如何使用Base64对图片进行编码)。上述两种用法分别为:

//参数可以传0至多个,size默认从一个数组中随机抽取一个,
//其余参数均有默认值,这里所有的参数都可以省略,size的
//格式为“720x300”,是一个字符串,详见官网
Random.image( size, background, foreground, format, text )
//dataImage只能定义宽高和文本
Random.dataImage( size, text )

3. 颜色

使用color()方法可以生成一个随机颜色,颜色为十六进制的格式,也可以生成其他格式的颜色值,方法如下:

Random.color()
// => "#3538B2"
Random.hex()
// => "#3538B2"
Random.rgb()
// => "rgb(242, 198, 121)"
Random.rgba()
// => "rgba(242, 198, 121, 0.13)"
Random.hsl()
// => "hsl(345, 82, 71)"

4. 文本

Mock可以模拟生成多种类型的文本,包括
paragraph(段落)、
sentence(句子)、
word(单词)、
title(标题)、
cparagraph(中文段落)、
csentence(中文句子)、
cword(中文词语)、
ctitle(中文标题)。
但是要注意,这里生成的文本实际上并不具备可读性,如Random.ctitle()可能输出“调有受记”。如果需要模拟可读的数据,请预先定义一组数据,然后从中随机抽取一条记录返回。

此外,这里的方法可以传入参数,来限制字符的长度,如Random.ctitle(5, 10),将生成一个包含5-10个字符的中文标题。

5. 名字

包括英文的姓、名、全名,以及中文的姓、名、全名。分别调用函数first()、last()、name()、cfirst()、clast()、cname()。这里生成的名字相对来说更加接近真实的人名,因此不需要再进行过多的处理。如

Random.name();
// => Nancy Thomas
Random.cname();
// => 梁丽  //此为mock随机生成,如有雷同,纯属巧合

6. web相关

url(资源地址)、
domain(域名)、
email(邮件地址)、
ip(IP地址)、
tId(顶级域名)、
protocol(协议)。

7. 地址

region(区划,如“华北”)、
provience(省份、自治区、直辖市或特别行政区)、
city(城市,如“合肥市”,调用city(true)将返回“安徽省 合肥市”)、
county(县,传入true同样会输出完整的省、市信息)、
zip(邮政编码,六位数字)。

8. 工具类

Random.capitalize( word ):将word的首字母转化为大写,
Random.upper( str ):将str全部转化为大写,
Random.lower( str ):将str全部转化为小写,
Random.pick( arr ):从数组中随机抽取一个元素,
Random.shuffle( arr ):随机打乱数组。

9. id类

Random.guid():生成一个全局唯一的GUID、
Random. id(): 生成一个随机的18位身份证号、
Random.increment( step? ):生成一个全局自增的整数。

总结

以上就是如何在vue中使用mockjs模拟后台数据以及mockjs的常用api,需要了解这些api详细用法的请访问mockjs官网查阅。除了这些直接提供的接口外,我们还可以对它们组合使用,生成更复杂的数据接口(如随机生成1-5条消息对象)。

目前来说,mockjs仍然无法直接模拟websocket。但是有一个变通的办法,就是用mock写一个接口,然后在前端使用setInterval循环调用,不过后期进行websocket连接时需要移除这部分代码。对于前端开发者来说,借助express(或koa、egg等),可以很容易使用nodejs搭建一个后端环境,并且可以直接连接到数据库。如果mockjs功能不能满足需要,nodejs也是我们一个有力的武器(如websocket就可以使用nodejs快速实现)。

总的来说,mockjs为前后端分离提供了强有力的支持,它本身的上手难度很低,可以说是前端开发者的必备技能,希望没有用过mockjs的同学可以尝试学习和使用。

往期精选

js基础之六种继承方式
js基础之原型链
V8引擎的内存管理分析
浏览器(基于Chromium)运行机制剖析
前端发展历程与技术应用概述
查看更多请点击关注

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章