Tips:一些记录,一些笔记

2024/03/23
SATURDAY
To master any skill takes a lifetime of hard work.
对任何技能的掌握都需要一生的刻苦操练。

01
Mock.JS
什么是「Mock」?
百度翻译的解释是这样的:

从字面意思上理解,它是一个用于「模拟」的工具,事实上,也确实如此。
Mock.JS的官方网站是:http://mockjs.com/

它的官方Github代码仓库:
https://github.com/nuysoft/Mock/tree/refactoring
它的官方文档:
https://github.com/nuysoft/Mock/wiki
它的官方示例:
http://mockjs.com/examples.html
02
安装
安装相关依赖:
(base) adamhuan@Leviathan vue-visible-abyss % pnpm add -D mockjs vite-plugin-mockWARN 5 deprecated subdependencies found: resolve-url@0.2.1, source-map-resolve@0.5.3, source-map-url@0.4.1, stable@0.1.8, urix@0.1.0Packages: +15+++++++++++++++Progress: resolved 616, reused 582, downloaded 0, added 15, donedevDependencies:+ mockjs 1.1.0+ vite-plugin-mock 3.0.1WARN Issues with peer dependencies found.└─┬ stylelint-config-prettier 9.0.5└── ✕ unmet peer stylelint@">= 11.x < 15": found 16.2.1Done in 3.9s(base) adamhuan@Leviathan vue-visible-abyss %
03
启用「Mock」
通常,Mock服务只用于开发阶段,因此,我们需要在配置文件中判断当前所处的环境。
在「vite.config.js」配置文件中启用「Mock」

该配置文件全文:
// ==================================// 导入// ==================================// 默认import { defineConfig, loadEnv } from "vite";import vue from "@vitejs/plugin-vue";// 基础模块import path from "path";// SVG 图标import { createSvgIconsPlugin } from "vite-plugin-svg-icons";// Mock.JSimport { viteMockServe } from "vite-plugin-mock";// ==================================// 定义// ==================================// https://vitejs.dev/config/export default defineConfig((config) => {const { command, mode } = config;const env = loadEnv(mode, process.cwd(), "");console.log(env.VITE_APP_TITLE);return {plugins: [// Vue.JSvue(),// Mock.JSviteMockServe({// Mock文件地址mockPath: "./mock",// 开发阶段:开启 Mock.JS 服务localEnabled: command === "dev",// 生产阶段:开启 Mock.JS 服务prodEnabled: command === "prod",injectCode: ``,// 控制台:显示请求日志logger: true,// 打开后:可以读取 TS文件模块,但是不再监听 JS文件模块supportTs: false,}),// SVG 图标createSvgIconsPlugin({// Specify the icon folder to be cached.iconDirs: [path.resolve(process.cwd(), "src/assets/icons")],// Specify symbolId formatsymbolId: "icon-[dir]-[name]",}),],resolve: {alias: {// 相对路径别名配置 - 使用 @ 替代 src"@": path.resolve("./src"),},},};});
04
Mock.JS「配置详解」
配置项:
{mockPath?: string;supportTs?: boolean;ignore?: RegExp | ((fileName: string) => boolean);watchFiles?: boolean;localEnabled?: boolean;ignoreFiles?: string[];configPath?: string;prodEnabled?: boolean;injectFile?: string;injectCode?: string;logger?:boolean;}
详解
| 配置项 | 数值类型与默认值 | 说明 | 详解 |
| mockPath | type: string default: mock | 设置「模拟的TS文件」的存储文件夹 | 如果「watchFiles: true」则将见识文件夹中的文件更改,并试试同步到请求结果; 如果「configPath」有值,则该配置项「无效」 |
| supportTs | type: boolean default: true | 打开后,可读取TS文件模块 | 打开后,将无法监视JS文件模块 |
| ignore | type: RegExp | ((fileName: string) => boolean) default: undefined | 自动读取「模拟TS文件」时,忽略指定格式的文件 | |
| watchFiles | type: boolean default: true | 设置是否监视 mockPath 对应的文件夹内,文件中的更改 | |
| localEnabled | type: boolean default: command === 'serve | 是否启用本地 XXX.TS文件 | 不要在生产环境中打开它; 设置为「false」将禁用 mock 功能 |
| prodEnabled | type: boolean default: command !== 'serve' | 打包是否启用 mock 功能 | |
| injectCode | type: string default: '' | 如果生产环境开启了 mock 功能,即「prodEnabled=true」,则代码会被注入到「injectFile」对应的文件底部,默认为「main.{ts,js}」 | 这样做的额好吃是:可以动态控制生产环境是否开启 mock,且在没有开启的时候 mock.js 不会被打包; 如果代码直接写在 main.js 内,则不管有没有开启,最终的打包都会包含 mock.js |
| injectFile | type: string default: path.resolve(process.cwd(), 'src/main.{ts,js}') | injectCode 代码注入的文件,默认为项目根目录「src/main.{ts,js}」 | |
| configPath | type: string default: vite.mock.config.ts | 设置模拟读取的数据条目 | 当文件存在并且位于项目根目录中时,将首先读取并使用该文件; 配置文件会返回一个数组 |
| logger | type: boolean default: true | 是否在控制台显示请求日志 |
05
Mock.JS「模拟数据文件的语法」
在项目的根目录创建文件夹「mock」,然后创建对应的模拟数据文件。
(base) adamhuan@Leviathan vue-visible-abyss % pwd/Users/adamhuan/Leviathan_VisibleAbyss_Base/vue-visible-abyss(base) adamhuan@Leviathan vue-visible-abyss %(base) adamhuan@Leviathan vue-visible-abyss % ls -ltr | grep mockdrwxr-xr-x 2 adamhuan staff 64 3 23 23:53 mock(base) adamhuan@Leviathan vue-visible-abyss %
Mock.JS 的语法规范包括两部分:
Data Template Definition DTD:数据模板定义规范
Data Placeholder Definition DPD:数据占位符定义规范
一、DTD 数据模板定义规范
数据模板中的每个属性由三个部分组成:
属性名 name
生成规则 rule
属性值 value
'name|rule':value
生成规则是可选的。
生成规则有7种格式:
'name|min-max': value'name|count': value'name|min-max.dmin-dmax': value'name|min-max.dcount': value'name|count.dmin-dmax': value'name|count.dcount': value'name|+step': value
生成规则的含义,需要依赖属性值的类型才能确定;
属性值中,可以含有「@」占位符;
属性值,制定了最终值的初始值与类型;
二、DPD / 数据占位符定义规范
占位符只是在属性值字符串中占个位置,并不出现在最终的属性值中。
格式:
@占位符(参数)
用「@」来标识后面的字符串是占位符;
占位符引用的是 Mock.Random 中的方法;
通过 Mock.Random.extend() 来扩展自定义占位符;
占位符也可以引用数据模板中的属性,并且是优先引用数据模板中的属性的;
占位符支持相对路径和绝对路径;
06
Mock.JS「新增模拟数据文件」
在「mock」中新增一个「模拟数据文件」:「helloworld.js」

文件「mock/helloworld.js」
export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok","data|1": {"01": "广西柳州","02": "上海","03": "深圳","04": "北京",},};},},];
然后,在命令行中你会发现跟进了这个变化:
00:15:01 [vite:mock] mock file add Users/adamhuan/Leviathan_VisibleAbyss_Base/vue-visible-abyss/mock/helloworld.js00:15:06 [vite:mock] mock file change Users/adamhuan/Leviathan_VisibleAbyss_Base/vue-visible-abyss/mock/helloworld.js
在页面上访问你配置的API「/api/helloworld」你就可以看到你的Mock.js的接口输出的内容了:


可以看到,就像我们接口中配置的那样,每次只会随机返回其中一条数据。
这就是一个「模拟接口」的简单定义与使用。
07
详细实例
因为Mock.JS支持DTD与DPD,并且它们各自也有很多的数据类型与写法,在这一小节中,我会以上面的「helloworld.js」为例,将所有的写法全部演示一遍。
为了简介,不再赘述其中的语法,只展示代码与页面结果的截图。
更详细的可以参考官方文档:http://mockjs.com/examples.html
08
DTD(数据模板定义)「详细示例」
String:
随机产生「1 - 10」个「*」
export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok","string|1-10": "*",};},},];

Number
随机产生「1 - 100」之间的任意数字
export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok","number|1-100": 5,};},},];

随机产生一个整数部分「1- 100」小数部分不超过「4」位的浮点数
export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok","number|1-100.1-4": 1,};},},];

Boolean
export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok","boolean|1": true,};},},];

Object
export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok","object|2": {1: "斗破苍穹年番",2: "与凤行",3: "死期将至",4: "在暴雪时分",5: "爱情而已",6: "执笔",7: "Ode to Joy",},};},},];

Array
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok","array|1": ["埃隆马斯克", "KK", "赵丽颖", "李一桐", "杨幂", "吴磊", "刘浩然"],};},},];

Function
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok",msg: "Stable Diffusion",sayHello: function () {return "我们拿到的消息是「" + this.msg + "」";},};},},];

RegExp
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok","regexp|3": /\d{5,10}\-/,};},},];

Path
Absolute Path
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok",folder01: "You found me.",nested: {level1: {level2: {level3: {folder02: "Here we are.",},},},},absolutePath: "@/folder01 @/nested/level1/level2/level3/folder02",};},},];

Relative Path
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok",foo: "Hello",nested: {a: {b: {c: "Mock.js",},},},relativePath: {a: {b: {c: "@../../../foo @../../../nested/a/b/c",},},},};},},];

09
DPD(数据占位符定义)「详细示例」
DPD,其实是由Mock.Random提供的方法;
Mock.Random 是一个工具类,用于生成各种随机数据
Mock.Random 的方法在数据模板中称为『占位符』,书写格式为 @占位符(参数)
它的完整表格如下所示:

以上这些是内置的方法,如果这些方法不够用,可以在「DTD数据模板」中,通过Mock.extend进行扩展,然后在数据模板中通过「@扩展方法」的方式引用。
例如:
import pkg from "mockjs";const { Random } = pkg;/* eslint-disable prettier/prettier */Random.extend({constellation: function () {let constellations = ["白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座", "水瓶座", "双鱼座"];return this.pick(constellations);},});export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok",constellations: "@CONSTELLATION",};},},];

下面演示内置方法的使用:
Basic: boolean
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok",boolean: "@boolean(1,9,true)",};},},];

Basic: natural
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok",natural: "@natural(60,400)",};},},];

Basic: integer
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok",integer: "@integer()",};},},];

Basic: float
// Random.float()Random.float()Mock.mock('@float')Mock.mock('@float()')// Random.float( min )Random.float(0)Mock.mock('@float(0)')// Random.float( min, max )Random.float(60, 100)Mock.mock('@float(60, 100)')// Random.float( min, max, dmin )Random.float(60, 100, 3)Mock.mock('@float(60, 100, 3)')// Random.float( min, max, dmin, dmax )Random.float(60, 100, 3, 5)Mock.mock('@float(60, 100, 3, 5)')
Basic: character
// Random.character()Random.character()Mock.mock('@character')Mock.mock('@character()')// Random.character( 'lower/upper/number/symbol' )Random.character('lower')Random.character('upper')Random.character('number')Random.character('symbol')Mock.mock('@character("lower")')Mock.mock('@character("upper")')Mock.mock('@character("number")')Mock.mock('@character("symbol")')// Random.character( pool )Random.character('aeiou')Mock.mock('@character("aeiou")')
Basic: string
// Random.string()Random.string()Mock.mock('@string')Mock.mock('@string()')// Random.string( length )Random.string(5)Mock.mock('@string(5)')// Random.string( pool, length )Random.string('lower', 5)Random.string('upper', 5)Random.string('number', 5)Random.string('symbol', 5)Random.string('aeiou', 5)Mock.mock('@string("lower", 5)')Mock.mock('@string("upper", 5)')Mock.mock('@string("number", 5)')Mock.mock('@string("symbol", 5)')Mock.mock('@string("aeiou", 5)')// Random.string( min, max )Random.string(7, 10)Mock.mock('@string(7, 10)')// Random.string( pool, min, max )Random.string('lower', 1, 3)Random.string('upper', 1, 3)Random.string('number', 1, 3)Random.string('symbol', 1, 3)Random.string('aeiou', 1, 3)Mock.mock('@string("lower", 1, 3)')Mock.mock('@string("upper", 1, 3)')Mock.mock('@string("number", 1, 3)')Mock.mock('@string("symbol", 1, 3)')Mock.mock('@string("aeiou", 1, 3)')
Basic: range
// Random.range( stop )Random.range(10)Mock.mock('@range(10)')// Random.range( start, stop )Random.range(3, 7)Mock.mock('@range(3, 7)')// Random.range( start, stop, step )Random.range(1, 10, 2)Random.range(1, 10, 3)Mock.mock('@range(1, 10, 2)')Mock.mock('@range(1, 10, 3)')
Date
// Random.date()Random.date()Mock.mock('@date')Mock.mock('@date()')// Random.date( format )Random.date('yyyy-MM-dd')Random.date('yy-MM-dd')Random.date('y-MM-dd')Random.date('y-M-d')Mock.mock('@date("yyyy-MM-dd")')Mock.mock('@date("yy-MM-dd")')Mock.mock('@date("y-MM-dd")')Mock.mock('@date("y-M-d")')Mock.mock('@date("yyyy yy y MM M dd d")')
Date: time
// Random.time()Random.time()Mock.mock('@time')Mock.mock('@time()')// Random.time( format )Random.time('A HH:mm:ss')Random.time('a HH:mm:ss')Random.time('HH:mm:ss')Random.time('H:m:s')Mock.mock('@time("A HH:mm:ss")')Mock.mock('@time("a HH:mm:ss")')Mock.mock('@time("HH:mm:ss")')Mock.mock('@time("H:m:s")')Mock.mock('@datetime("HH H hh h mm m ss s SS S A a T")')
Date: datetime
// Random.datetime()Random.datetime()Mock.mock('@datetime')Mock.mock('@datetime()')// Random.datetime( format )Random.datetime('yyyy-MM-dd A HH:mm:ss')Random.datetime('yy-MM-dd a HH:mm:ss')Random.datetime('y-MM-dd HH:mm:ss')Random.datetime('y-M-d H:m:s')Mock.mock('@datetime("yyyy-MM-dd A HH:mm:ss")')Mock.mock('@datetime("yy-MM-dd a HH:mm:ss")')Mock.mock('@datetime("y-MM-dd HH:mm:ss")')Mock.mock('@datetime("y-M-d H:m:s")')Mock.mock('@datetime("yyyy yy y MM M dd d HH H hh h mm m ss s SS S A a T")')
Date: now
// Ranndom.now()Random.now()Mock.mock('@now')Mock.mock('@now()')// Ranndom.now( unit )Random.now('year')Random.now('month')Random.now('week')Random.now('day')Random.now('hour')Random.now('minute')Random.now('second')// Ranndom.now( format )Random.now('yyyy-MM-dd HH:mm:ss SS')// Ranndom.now( unit, format )Random.now('day', 'yyyy-MM-dd HH:mm:ss SS')
Image
/* eslint-disable prettier/prettier */export default [{url: "/api/helloworld",method: "get",response: () => {return {code: 0,message: "ok",image: "@image('200x100','#50b347','#FFF','png','Hello')",};},},];

Color
// Random.color()Random.color()Mock.mock('@color')Mock.mock('@color()')// Random.hex()Random.hex()Mock.mock('@hex')Mock.mock('@hex()')// Random.rgb()Random.rgb()Mock.mock('@rgb')Mock.mock('@rgb()')// Random.rgba()Random.rgba()Mock.mock('@rgba')Mock.mock('@rgba()')// Random.hsl()Random.hsl()Mock.mock('@hsl')Mock.mock('@hsl()')
Text
// Random.paragraph()Random.paragraph()Mock.mock('@paragraph')Mock.mock('@paragraph()')// Random.paragraph( len )Random.paragraph(2)Mock.mock('@paragraph(2)')// Random.paragraph( min, max )Random.paragraph(1, 3)Mock.mock('@paragraph(1, 3)')// Random.sentence()Random.sentence()Mock.mock('@sentence')Mock.mock('@sentence()')// Random.sentence( len )Random.sentence(5)Mock.mock('@sentence(5)')// Random.sentence( min, max )Random.sentence(3, 5)Mock.mock('@sentence(3, 5)')// Random.word()Random.word()Mock.mock('@word')Mock.mock('@word()')// Random.word( len )Random.word(5)Mock.mock('@word(5)')// Random.word( min, max )Random.word(3, 5)Mock.mock('@word(3, 5)')// Random.title()Random.title()Mock.mock('@title')Mock.mock('@title()')// Random.title( len )Random.title(5)Mock.mock('@title(5)')// Random.title( min, max )Random.title(3, 5)Mock.mock('@title(3, 5)')// Random.cparagraph()Random.cparagraph()Mock.mock('@cparagraph')Mock.mock('@cparagraph()')// Random.cparagraph( len )Random.cparagraph(2)Mock.mock('@cparagraph(2)')// Random.cparagraph( min, max )Random.cparagraph(1, 3)Mock.mock('@cparagraph(1, 3)')// Random.csentence()Random.csentence()Mock.mock('@csentence')Mock.mock('@csentence()')// Random.csentence( len )Random.csentence(5)Mock.mock('@csentence(5)')// Random.csentence( min, max )Random.csentence(3, 5)Mock.mock('@csentence(3, 5)')// Random.cword()Random.cword()Mock.mock('@cword')Mock.mock('@cword()')// Random.cword( pool )Random.cword('零一二三四五六七八九十')Mock.mock('@cword("零一二三四五六七八九十")')// Random.cword( length )Random.cword(3)Mock.mock('@cword(3)')// Random.cword( pool, length )Random.cword('零一二三四五六七八九十', 3)Mock.mock('@cword("零一二三四五六七八九十", 3)')// Random.cword( min, max )Random.cword(3, 5)Mock.mock('@cword(3, 5)')// Random.cword( pool, min, max )Random.cword('零一二三四五六七八九十', 5, 7)Mock.mock('@cword("零一二三四五六七八九十", 5, 7)')// Random.ctitle()Random.ctitle()Mock.mock('@ctitle')Mock.mock('@ctitle()')// Random.ctitle( len )Random.ctitle(5)Mock.mock('@ctitle(5)')// Random.ctitle( min, max )Random.ctitle(3, 5)Mock.mock('@ctitle(3, 5)')
Name
// Random.first()Random.first()Mock.mock('@first')Mock.mock('@first()')// Random.last()Random.last()Mock.mock('@last')Mock.mock('@last()')// Random.name()Random.name()Mock.mock('@name')Mock.mock('@name()')// Random.name( middle )Random.name(true)Mock.mock('@name(true)')// Random.cfirst()Random.cfirst()Mock.mock('@cfirst')Mock.mock('@cfirst()')// Random.clast()Random.clast()Mock.mock('@clast')Mock.mock('@clast()')// Random.cname()Random.cname()Mock.mock('@cname')Mock.mock('@cname()')
Web
// Random.url()Random.url()Mock.mock('@url')Mock.mock('@url()')// Random.domain()Random.domain()Mock.mock('@domain')Mock.mock('@domain()')// Random.protocol()Random.protocol()Mock.mock('@protocol')Mock.mock('@protocol()')// Random.tld()Random.tld()Mock.mock('@tld')Mock.mock('@tld()')// Random.email()Random.email()Mock.mock('@email')Mock.mock('@email()')// Random.ip()Random.ip()Mock.mock('@ip')Mock.mock('@ip()')
Address
// Random.region()Random.region()Mock.mock('@region')Mock.mock('@region()')// Random.province()Random.province()Mock.mock('@province')Mock.mock('@province()')// Random.city()Random.city()Mock.mock('@city')Mock.mock('@city()')// Random.city( prefix )Random.city(true)Mock.mock('@city(true)')// Random.county()Random.county()Mock.mock('@county')Mock.mock('@county()')// Random.county( prefix )Random.county(true)Mock.mock('@county(true)')// Random.zip()Random.zip()Mock.mock('@zip')Mock.mock('@zip()')
Helper
// Random.capitalize( word )Random.capitalize('hello')Mock.mock('@capitalize("hello")')// Random.upper( str )Random.upper('hello')Mock.mock('@upper("hello")')// Random.lower( str )Random.lower('HELLO')Mock.mock('@lower("HELLO")')// Random.pick( arr )Random.pick(['a', 'e', 'i', 'o', 'u'])Mock.mock('@pick(["a", "e", "i", "o", "u"])')// Random.shuffle( arr )Random.shuffle(['a', 'e', 'i', 'o', 'u'])Mock.mock('@shuffle(["a", "e", "i", "o", "u"])')
Miscellaneous
// Random.guid()Random.guid()Mock.mock('@guid')Mock.mock('@guid()')// Random.id()Random.id()Mock.mock('@id')Mock.mock('@id()')// Random.increment()Random.increment()Mock.mock('@increment')Mock.mock('@increment()')// Random.increment( step )Random.increment(100)Mock.mock('@increment(100)')Random.increment(1000)Mock.mock('@increment(1000)')
END
温馨提示
如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注我。




