mockjs学习与实践一文通杀

119 阅读5分钟

快速入门+方便cv

由于mock实现模拟一个数据可能有多种方式,官方文档的聚集方式有点散,第一部分仅摘录最核心的常用认识及用法

mock案例

基础概念

  • "键名|x": 数据字面量
  • "键名|x-y": 数据字面量

根据后面数据类型的不同,意义不同
数据类型为string 就是重复次数x次/x-y次
数据类型为array 从数组里取x个/x-y个 组成新数组
数据类型为number x-y是数据范围内取值//见案例 (字面量仅起决定数据类型的作用)

使用mock.random

  • Random.natural() 写成 '@natural' 考虑到可能要传参 用反引号更方便
  • customerCount: `@natural(10,1000)`,
  • customerCount: `@natural`, //不传参时 不需要写括号
  • "string|3": "a" //要把a重复3遍
  • string:"a" //若不需要使用数据模板功能时,键名没必要当字符串

常用mock的类型合成的综合使用案例

Mock.mock({ 
  'list|8-20': [
    {
      //----------数字---------------
      'add|+1': 10,//从10开始,执行一次自增1
      addR: `@increment(3)`,//自增3
      'id|3-10': 0,//生成3-10之间的整数
      idR: `@integer(3,10)`,//生成3-10之间的整数
      numFloatR: `@float(60, 100, 0, 2)`,//60~100之间的小数,0~2个小数位
      //----------布尔---------------
      'isShow|1': Boolean,//1/2概率为true(实测都是true 不建议用)
      'isShow2|3-7': true,// 3/10概率为true
      show: `@boolean`,
      show2: `@boolean(3,7,true)`,// 3/10概率为true
      //----------字符串--------------
       //对于生成固定文字组合的字符串,建议用正则方法,随心所欲
      class: /[一二三]年级[一二三]班/, 
      date: `@date('yyyy-MM-dd')`,
      time: `@time('HH:mm:ss')`,
      paragraph: `@paragraph( 1,3 )`,//生成英语句子,1到3句
      paragraphC: `@cparagraph(1,3)`,
      name: `@cname`,//生成中文名
      url: `@url('http', 'github.com')`,//该域名下的某个网址
      email: `@email`,
      address: `@county(true)`,//省市区
      uid: `@guid`,//生成全局唯一id
      idCard: `@id`,//生成身份证号码
    },
  ],
})

mock在项目中的使用

mock拦截url

  • 对测试环境的url进行拦截,一般来说只是一些接口需要mock,下面这种方案够用
  • Mock.mock仅拦截某个特定的接口,不会对其它接口的ajax请求有影响
//-----mock/index.js------------main.js引入该文件即可拦截请求-----
import Mock from "mockjs";
const baseURL = "http://test.myapi.com";
const baseResult = {
  code: 0,
  message: "操作成功",
  data: null,
};

// 顶部绑定企微 列表
Mock.mock(turnToReg('/account-list'), "get", (options) => {
// console.log(JSON.parse(options.body))
  const data = Mock.mock({
    data: {
      "list|3-8": [
        {
          id: "@guid",
          name: "@cname()", //中文名
          tel: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
          corpId: "@natural(10,300)", //type 1
          imgUrl: `@image(200x100)`,
          "onlineStatus|1": true,
        },
      ],
    },
  });
  return Object.assign(baseResult, data);
});

function joinPath(url){
    return baseURL+url
}
// get请求 由于连接是 url?xx=xxxx 靠字符串url无法匹配
function turnToReg(url){
    return RegExp(baseURL+url+ ".*")
}

Mock.mock()

main.js动态引入

  • 由于test环境才需要mock,main.js直接import整个mock文件打包后是个累赘
  • import "./mock/index" 是静态引入
  • import("./mock/index") 是动态引入,会返回一个promise
------main.js-------
// 方案一: 实践证明,import("./mock/index");有的项目起效,有的项目里不起效
if (process.env.NODE_ENV === "development") {
  import("./mock/index");
}

// 方案二: 稳妥做法
process.env.NODE_ENV == "development"&& require('./mock/index'); 

mdn动态import

mock数据构造学习

文档:github.com/nuysoft/Moc…

通过 数据模板/数据占位符 来模拟动态生成数据

个人理解

  1. 数据模板用来搞限定数字方便决定数据结构,字符串是设置重复次数(弱控制),也可以通过正则随心所欲
  2. 数据占位符覆盖常见数据模式,建议除了数字和外部数据结构外 尽量用数据占位符决定字段值

暂时拟定使用模式:尽可能使用数据占位符规范造数据,对于需要传参的 外层用 ` 反引号包裹

1. 数据模板规范

      'name|min-max': value//字符串重复min-max次
      'name|count': value //字符串重复count次
      'name|min-max.dmin-dmax': value //小数部分保留dmin-dmax位
      'name|min-max.dcount': value
      'name|count.dmin-dmax': value
      'name|count.dcount': value
      'name|+step': value
      
    let test1 = Mock.mock({
      // 写 x-y 是重复次数或数字范围,只写x 即固定值的某个位
      'str|3-5': '归去来兮', //生成规则:重复次数
      'num|3-5': 1, //生成规则:取值范围
      'num|5-30.1-3': 1, //属性值只是为了确定类型
      'numFix|9.1-5': 1, //整数部分固定为9
      'numCnt|5-10.3': 1,
    })  
    
      let test2 = Mock.mock({
      'list|10': [
        {
          'autoAdd|+1': 5,
          'even|1': true, //生成布尔值
          'diff|3-7': true, //值为true的概率 3/7+3
          // 根据正则表达式 regexp 反向生成可以匹配它的字符串。
          regexp1: /[a-z][A-Z][0-9]/,
          first: '@first',
        },
      ],
    })

  • @占位符
  • @占位符(参数 [, 参数])
  • 占位符 引用的是 Mock.Random 中的方法。
    mockjs.com/examples.ht… Mock.Random方法全图鉴

2. 数据占位符规范

  • Mock.Random 提供的完整方法(占位符)如下://这些方法不传参也能用
TypeMethod
Basicboolean, natural, integer, float, character, string, range, date, time, datetime, now
Imageimage, dataImage
Colorcolor
Textparagraph, sentence, word, title, cparagraph, csentence, cword, ctitle
Namefirst, last, name, cfirst, clast, cname
Weburl, domain, email, ip, tld
Addressarea, region
Helpercapitalize, upper, lower, pick, shuffle
Miscellaneousguid, id
var Random = Mock.Random
Random.email()
// => "n.clark@miller.io"
Mock.mock('@email')
// => "y.lee@lewis.org"
Mock.mock( { email: '@email' } )
// => { email: "v.lewis@hall.gov" }
first: '@first', =>英文名字的姓
  • 核心案例//数据模板规范里造的数据 这种方式一样能造 且更方便
    let test3 = Mock.mock({
      'list|5': [
        {
          //由于" '引号的问题 对于要传参的 外层用 `
          date: `@date("yyyy-MM-dd")`,
          integer: `@integer(10,30)`,
          float: `@float(5,10,2,5)`, //min?, max?, dmin?, dmax?
          //不传参数生成随机字符串
          string: `@string("壹贰叁肆伍陆柒捌玖拾", 3, 5 )`,
          paragraph: `@paragraph()`,
          // 生成指定宽高的图片 可指定图片格式默认png
          img: `@image("200x100", "#fb0a2a")`,
          //随机生成base64图片编码 推荐!
          dataImg: `@dataImage("400x400","哈哈哈")`,
          color: `@color()`,
          name: '@cname()', //中文名
          eName: `@first() @last()`, //英文名
          url: `@url('http', 'evasuka.com')`,
          addr: `@county(true)`,
          autoAdd: `@increment(10)`,//全局自增 调用一次增加10
        },
      ],
    })
  • Mock.Random 中的方法与数据模板的 @占位符 一一对应,在需要时还可以为 Mock.Random 扩展方法,然后在数据模板中通过 @扩展方法 引用。例如:
Random.extend({
    constellation: function(date) {
        var constellations = ['白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座', '水瓶座', '双鱼座']
        return this.pick(constellations)
    }
})
Random.constellation()
// => "水瓶座"
Mock.mock('@CONSTELLATION')
// => "天蝎座"
Mock.mock({
    constellation: '@CONSTELLATION'
})
// => { constellation: "射手座" }