在前端开发中,如果需要模拟后端数据,而又不想开发一个后端服务器, 则可以借助mock.js配置一个后端服务器来返回前端需要的数据,本文将会分别介绍在Quasar项目和Vite项目中Mock服务器的配置方法。
Vite项目的初始化按照官网上的教程进行:
yarn create vite
创建项目后,再安装Mock相关插件:
yarn add -D mockjs yarn add -D vite-plugin-mock yarn add axios
在对Vite进行配置之前,需要先编辑根目录下的tsconfig.node.json
,然后把里面的include
内的内容删除,否则在配置Vite的时候会报错,删除后的文件如下:
// tsconfig.node.json { "compilerOptions": { "composite": true, "module": "ESNext", "moduleResolution": "Node", "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] }
这里借鉴NaiveUI Admin的设计思路,将Vite的所有插件的配置分离出去,通过函数进行返回,来实现模块化开发,具体的做法是:
在本文的场景中,各文件的内容如下:
vite/plugins/index.ts
// vite/plugins/index.ts import type { Plugin } from 'vite'; import vue from '@vitejs/plugin-vue'; import { configMockPlugin } from './mock'; export function createVitePlugins() { // 初始插件,在这里导入其他框架的resolver const vitePlugins: (Plugin | Plugin[])[] = [ vue(), ]; // vite-plugin-mock vitePlugins.push(configMockPlugin(true, true)); // 下面可以添加其他的插件 // vitePlugins.push(...); return vitePlugins; }
vite/plugins/mock.ts
// plugin/mock.ts import { viteMockServe } from 'vite-plugin-mock'; export function configMockPlugin(isBuild: boolean, prodMock: boolean) { return viteMockServe({ ignore: /^\_/, mockPath: 'mock', localEnabled: !isBuild, prodEnabled: isBuild && prodMock, injectCode: ` import { setupProdMockServer } from '../mock/_createProductionServer'; setupProdMockServer(); `, }); }
vite.config.ts
// vite.config.ts import { UserConfig, ConfigEnv, defineConfig } from 'vite'; import { createVitePlugins } from './vite/plugins'; // https://vitejs.dev/config/ export default defineConfig(({ command, mode }: ConfigEnv): UserConfig => { return { plugins: createVitePlugins(), } })
至此,Vite方面的配置已经完毕,下面就可以配置Mock的返回接口了。
同样地,我们在项目根目录下创建一个文件夹来存放Mock相关的文件,这里命名为Mock
,该目录的结构说明如下:
mock ├── module1 业务模块1 │ ├── mock1.ts 数据接口1 │ └── mock2.ts 数据接口2 ├── module1 业务模块2 │ ├── mock1.ts 数据接口1 │ └── mock2.ts 数据接口2 ├── index.ts 导出所有接口 └── _util.ts 对返回值的一些处理
有时候我们需要模拟表格数据,而Mock提供的随机数据接口一次只能返回一条数据,我们可以自己封装一个函数来处理这种需要返回多个数据的情况,这里还是借鉴NaiveUI Admin的做法:
// _utils.ts 一些工具函数, 可用来处理返回的请求 import { mock } from 'mockjs'; // 包装返回的数据 export function resultSuccess(result, { message = 'ok' } = {}) { return mock({ code: 200, result, message, type: 'success', }); } export function resultError(message = 'Request failed', { code = -1, result = null } = {}) { return { code, result, message, type: 'error', }; } export function resultPageSuccess<T = any>( page: number, pageSize: number, list: T[], { message = 'ok' } = {} ) { const pageData = pagination(page, pageSize, list); return { ...resultSuccess({ page, pageSize, pageCount: list.length, list: pageData, }), message, }; } // export function pagination<T = any>(pageNo: number, pageSize: number, array: T[]): T[] { const offset = (pageNo - 1) * Number(pageSize); const ret = offset + Number(pageSize) >= array.length ? array.slice(offset, array.length) : array.slice(offset, offset + Number(pageSize)); return ret; } /** * @param {Number} times 回调函数需要执行的次数 * @param {Function} callback 回调函数 */ export function doCustomTimes(times: number, callback: any) { let i = -1; while (++i < times) { callback(i); } } export interface requestParams { method: string; body: any; headers?: { token?: string }; query: any; } /** * @description 本函数用于从request数据中获取token,请根据项目的实际情况修改 * */ export function getRequestToken({ headers }: requestParams): string | undefined { return headers?.token; }
现在,按照业务进行模拟接口的编写,这里展示一个示例,返回一个人员信息表格的模拟数据:
// mock/table/list.ts 一个返回表格数据的接口 import { Random } from 'mockjs'; import { resultSuccess, doCustomTimes } from '../_utils'; const tableList = (pageSize) => { const result: any[] = []; doCustomTimes(pageSize, () => { result.push({ id: '@integer(10,999999)', beginTime: '@datetime', endTime: '@datetime', address: '@city()', name: '@cname()', avatar: Random.image('400x400', Random.color(), Random.color(), Random.first()), date: `@date('yyyy-MM-dd')`, time: `@time('HH:mm')`, 'no|100000-10000000': 100000, 'status|1': [true, false], }); }); return result; }; export default [ //表格数据列表 { url: '/api/table/list', timeout: 1000, method: 'get', response: ({ query }) => { const { page, pageSize } = query; const list = tableList(Number(pageSize)); return resultSuccess({ page: Number(page), pageSize: Number(pageSize), pageCount: 60, list, }); }, }, ];
关于怎么在Vue中使用Axios,请参考其他的文章,这里假设已经完成了Axio的封装,在组件中直接调用设置好的接口就可以获取数据了,而且命令行中还会显示调用记录:
<script setup lang="ts"> import { ref } from 'vue'; import service from '../axios'; const text = ref('123'); const getdata = () => { service .get('/table/list', { params: { page: Math.round(Math.random()*10) + 1, pageSize: Math.round(Math.random()*10) + 1, }, }) .then((res) => { text.value = res.data; }); }; </script> <template> <button @click="getdata">click</button> <p>{{text}}</p> </template>
在这里推荐一下这个框架,非常好用,快去它的官网看看吧。我们这里还是以官方初始模板为基础进行配置。
# 全局安装quasar脚手架 npm install -g @quasar/cli yarn create quasar # 注意选择vite作为打包工具, 进入目录后 yarn yarn add -D mockjs yarn add -D vite-plugin-mock
需要注意的是,网络上有人提供了基于boot文件的解决方案,这种方案可以正常返回数据,但是不能在命令行显示调用记录,而且在浏览器中也看不到网络请求,调试起来不太方便,因此经过探索,只需要将Vite插件的配置直接复制到quasar.config.js中的build.vitePlugins中即可,修改过后的Quasar配置文件的部分显示如下:
// 导入mock服务器的函数 const viteMockServe = require('vite-plugin-mock').viteMockServe build: { // 添加mock插件 vitePlugins: [ [ viteMockServe({ ignore: /^\_/, mockPath: 'mock', localEnabled: !isBuild, prodEnabled: isBuild && prodMock, injectCode: ` import { setupProdMockServer } from '../mock/_createProductionServer'; setupProdMockServer(); `, }) ] ] }
这一部分的文件与Vite项目完全一样,就不再赘述
同Vite项目,关键是要封装Axios
在这里推荐一个好用的API工具,ApiFox,可以很方便的模拟接口数据,而且有其他开发者分享的API接口,十分好用。