设计目标

在前端数据模拟库上,已经有像 fakerjsmockjs 这种功能比较全的库,但每个库都有自己的设计风格和出发点。suchjs 的设计目标主要有如下两个方面:

  • 易扩展 —— 对于数据模拟来说,良好的扩展性是保持库的生命力的一个重要特性,所以suchjs在这方面做了尽可能多的设计和工作。

  • 易使用 —— 这其实是易扩展带来的一个好处之一,另外 suchjs 采用声明式的写法,以多种数据属性配置组合的方式来声明数据,这种方式更便于理解。

数据属性

每种数据类型都有其具备的自身特性,比如数字,会有大小、会有格式;又比如字符串会有长度,会有字符语言的限制,或者说 unicode 码点的限制。suchjs 把这些通用特性提取出来,以数据属性的方式书写在类型描述中。也因此一个模拟数据可能是多个这样的数据属性的组合,多个数据属性通过间隔符 : 隔离开来(注:为有时候方便书写,第一个类型属性和紧接着的属性的分隔符可以省略)。suchjs 里内置的数据属性包含以下这些:

  • 类型 —— 首先需要书写数据的类型,这些类型可以是 suchjs 内置的,也可以是你自己定义的。默认的内置类型有字符串 :string,数字 :number,日期 :date,正则 :regexp,引用 :ref,自增 :increment,还支持词典 :dict,级联菜单 :cascader,不过这两个类型在 Nodejs 环境和浏览器环境使用上有稍许区别,在具体类型的条目上会有相关的说明。此外还包括内置的扩展类型如 :bool:int:url:email 等,内置扩展类型可以也可以在源代码 src/extends/recommend.ts 查看。

  • 长度 —— 长度属性以 {min[,max]} 的格式书写,它通常对于字符串和数组格式数据比较常用,如字符串长度为 3 则用 {3} 表示,长度为 10 到 20 则表示为 {10,20}

  • 大小 —— 大小属性以 [min,max] 的格式书写,通常表示一个数值范围。对于数字,就表示数字的最小值和最大值,如数字大小为 10 到 20,则用 [10,20] 表示,如果表示一个固定数字,比如数字 3,则用 [3,3] 表示,如果不是有其它的数据属性配置,则更应该直接用数字 3 直接书写。对于字符串,则通常表示字符的码点范围,比如大写字母的码点范围为 65-90,则可以书写为[65,90],如果有多个分组,则可以用分组的书写语法,比如同时表示大写字母和小写字母,可以书写为[65-90,97-122]。对于日期,则表示一个日期范围,比如从 2012 到 2022,则表示为 [2012,2022]suchjs内置了更强大的类似 php strtotime 日志格式的支持,比如以当前时间前后 5 年的范围,则可以表示为 ['-5 years','+5 years']

  • 格式化 —— 格式化属性以 % 后面带上 format 格式的方式书写。格式化通常对于数字类型、日期类型比较有用,对于数字类型,suchjs 内置了支持 c 风格 printf 的书写格式,比如 %.2f 表示将数字转成 2 位小数点的浮点数(数字类型默认就是小数部分生成Math.random浮点数的格式)。

  • 路径 —— 路径属性以 & 后带上地址的形式书写。路径属性对引用类型、词典类型等比较有用。对于引用类型,路径地址代表着模拟对象的数据路径,注意路径对应的引用字段必须出现在该引用类型之前,否则获取到的数据将是undefined{firstName: '你', lastName: '好', fullName: ':ref:&./firstName,./lastName'},这样 fullName 将得到 ['你','好']的一个数组。对于词典类型,则表示词典文件的路径地址 :dict:&<dataDir>/dict.txt,则表示从数据目录下的 dict.txt 文件获取数据。

  • 正则 —— 匹配正则以 / 开头,后接正则表达式字符串。正则的属性配置主要针对正则类型。正则类型是一个很强大的类型,基于它能生成基本你想要的格式的所有类型。

  • 函数调用 —— 以上的数据属性不同的数据类型可能并不是都需要,所以每个类型可能都只支持特定的几种数据属性的写法,但函数调用和下面的配置数据属性则是所有类型都支持解析的。函数属性以 @ 开头,后面加上函数调用,要使用的函数可以通过Such.assign静态方法全局注入,对于数据类型自身存在的方法,则可以直接调用。比如对于字符串类型::string:[65,90]:{3}:@repeat(3)|slice(-5),则表示获取到 3 个大写字母字符串后、重复 3 遍,然后取最后倒数的 5 个字符。

  • 参数配置 —— 参数配置和函数调用一样,也是类型默认都支持解析并获取到的数据属性。它通常用来为一些已定义类型提供外部数据的注入。参数配置以 #[key=value,flag]的格式书写。比如自增 id 类型,我们想配置它的开始值和步阶,则可以这样配置 :increment:#[start=1,step=2]

数据模拟示例

有了对上面数据属性基础的了解,现在我们就可以来通过这些数据属性的组合,来模拟一些数据了。

  • :string:[65,90]:{3,10} => 输出一个字符串,字符串的码点范围为 65 到 90<亦即大写字母>,长度为 3 到 10 个,会生成形如 DUFCDKASGDS 这样的字符串。

  • :date:['-1 year','+1 year']:%yyyy-mm-dd HH\:MM\:ss => 输出当前日期前后一年的日期,并格式化为年月日时分秒的形式。

  • :number:[1,100]:%.2f => 输出一个 1 到 100 内的数字,并且格式化为保留两个小数点。

  • :regexp:/[a-z]{3,5}/i => 输出一个 3 到 5 个英文字母的字符串。

更多的数据类型或者类型自定义方式请继续查看相关章节。