广州网站关键词优化推广seo关键词优化培训
前段时间在将两个不同的业务分支合并时(可参考一套vue代码根据环境变量实现不同环境功能定制化——案例分享),发现mock文件夹下面有大量差异的json内容,看了一眼提交记录为21
年,最近这两年该文件夹内容都没有变更。
查寻资料发现mock是用于前端模拟后端响应,往往用于前后端分离开发,前端和后端并行开发用。
考虑团队从22
年开始就强推全栈开发,往往一个人包揽前后端开发,平时调试时一般直接调用本地接口或线上测试环境接口,或许前端的mock功能渐渐就被弃用了。
考虑到最近几篇博客围绕的前端项目hello_vue3都会涉及到后端接口的调用(见vue3配置代理实现axios请求本地接口返回PG库数据【前后端实操】),读者还需要维护一个本地后端,比较繁琐,计划引入mock技术,对于部分页面提供调用mock和本地接口开关
,实现单纯前端也能进行初步调试,本文主要说明vue3 + vite + ts 环境下mock搭建、使用、以及遇到的问题 。
效果showCase
代码仓
https://gitee.com/pinetree-cpu/hello_vue3
mock环境搭建
安装依赖
npm install vite-plugin-mock mockjs --save-dev
# 或者
yarn add vite-plugin-mock mockjs -D
配置 vite.config.ts
关注viteMockServe()
内部配置
import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import { viteMockServe } from 'vite-plugin-mock'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),vueDevTools(),viteMockServe({mockPath: 'src/mock', // mock文件存放目录enable: true,logger: true, // 是否在控制台显示请求日志watchFiles: true // 监视文件更改})],server: {proxy: {'/asset': { // 以 '/asset' 开头的请求会被代理target: 'http://localhost:8888', // 后端服务器地址changeOrigin: true, // 允许跨域rewrite: (path) => path.replace(/^\/asset/, '') // 重写路径,去掉 '/asset'}}},resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}}
})
创建mock文件
在项目根目录下创建 mock 文件夹,创建assetInfo_mock.ts
,本文主要mockvue3配置代理实现axios请求本地接口返回PG库数据【前后端实操】)中的资产信息
定义mock VO类型
在src/types/index.ts
中添加
// mock资产表单
export interface MockAssetFormData {assetNumber: string;assetStatus: string;extAttribute1: string;extAttribute2: string;extAttribute3: string;extAttribute4: string;extAttribute5: string;extAttribute6: string;extAttribute7: string;extAttribute8: string;extAttribute9: string;extAttribute10: string;bizId: string;
}// 响应VO
export interface ResultVO<T = any> {code: number;isSuccess: boolean;message: String;data: T;
}
定义mock数据响应逻辑逻辑
import { MockMethod } from 'vite-plugin-mock'
import type { MockAssetFormData, ResultVO} from "@/types";const assetInfoMockList: MockAssetFormData[] = [{"bizId": "0777c40218114c35a29b0d4d84355668","assetNumber": "0777c40218114c35a29b0d4d8435520e","assetStatus": "10","extAttribute1": "mock_ext_attribute1","extAttribute2": "mock_ext_attribute2","extAttribute3": "mock_ext_attribute3","extAttribute4": "mock_ext_attribute4","extAttribute5": "mock_ext_attribute5","extAttribute6": "mock_ext_attribute6","extAttribute7": "mock_ext_attribute7","extAttribute8": "mock_ext_attribute8","extAttribute9": "mock_ext_attribute9","extAttribute10": "mock_ext_attribute10",},{"bizId": "0777c40218114c35a29b0d4d84355668","assetNumber": "2d72bf99ebcad018297aed761b5dee8d","assetStatus": "10","extAttribute1": "mock_ext_attribute1","extAttribute2": "mock_ext_attribute2","extAttribute3": "mock_ext_attribute3","extAttribute4": "mock_ext_attribute4","extAttribute5": "mock_ext_attribute5","extAttribute6": "mock_ext_attribute6","extAttribute7": "mock_ext_attribute7","extAttribute8": "mock_ext_attribute8","extAttribute9": "mock_ext_attribute9","extAttribute10": "mock_ext_attribute10",},{"bizId": "0777c40218114c35a29b0d4d84355998","assetNumber": "good-giao","assetStatus": "10","extAttribute1": "mock_ext_attribute1","extAttribute2": "mock_ext_attribute2","extAttribute3": "mock_ext_attribute3","extAttribute4": "mock_ext_attribute4","extAttribute5": "mock_ext_attribute5","extAttribute6": "mock_ext_attribute6","extAttribute7": "mock_ext_attribute7","extAttribute8": "mock_ext_attribute8","extAttribute9": "mock_ext_attribute9","extAttribute10": "mock_ext_attribute10",}
]export default [{url: '/mock/asset/assetInfo',method: 'post',response: (body): ResultVO<Map<String, Array<MockAssetFormData>>> => {console.log('body', body)const bizId = body.body.bizIdconsole.log('bizId', bizId)const matchAssetInfo = assetInfoMockList.filter(item => item.bizId === bizId)const dataMap = new Map<String, Array<MockAssetFormData>>dataMap.set('assetInfoList', matchAssetInfo)console.log('dataMap', dataMap)const dataObj = Object.fromEntries(dataMap)console.log('dataObj', dataObj)return {code: matchAssetInfo.length > 0 ? 300 : 404,data: dataObj,isSuccess: matchAssetInfo.length > 0,message: matchAssetInfo.length > 0 ? 'success' : 'asset not found'}}}
] as MockMethod[]
请求mock数据
// 请求mock数据await axios.post('/mock/asset/assetInfo', { bizId }).then(result => {const assetInfoList: Array<AssetFormData> = result?.data?.data?.assetInfoListconsole.log('assetInfoList', assetInfoList)tabs.value = []assetInfoList.forEach((asset, idx) => {const newTabName = `表单 ${idx + 1}`tabs.value.push({label: newTabName,name: newTabName,insertForm: asset})activeTab.value = newTabName})})
遇到的问题汇总
mock里面console.log和debugger没有效果
例如下方代码块内容,不会在浏览器控制台输出
export default [{url: '/mock/asset/assetInfo',method: 'post',response: (body): ResultVO<Map<String, Array<MockAssetFormData>>> => {console.log('body', body)const bizId = body.body.bizIdconsole.log('bizId', bizId)const matchAssetInfo = assetInfoMockList.filter(item => item.bizId === bizId)const dataMap = new Map<String, Array<MockAssetFormData>>dataMap.set('assetInfoList', matchAssetInfo)console.log('dataMap', dataMap)const dataObj = Object.fromEntries(dataMap)console.log('dataObj', dataObj)return {code: matchAssetInfo.length > 0 ? 300 : 404,data: dataObj,isSuccess: matchAssetInfo.length > 0,message: matchAssetInfo.length > 0 ? 'success' : 'asset not found'}}}
] as MockMethod[]
问题根因:
Mock 代码通常运行在 Node.js 环境或特殊的中间件层,而不是浏览器上下文
表现:
console.log 输出会出现在终端/服务器日志中,而不是浏览器控制台
debugger 语句在服务端环境中无法触发浏览器调试器
解决措施:
在Node终端查看
返回Map对象时为空
根据bizId成功获取到matchAssetInfo
后,计划按照后端接口返回的格式进行组装成dataMap
,console.log显示存在数据,但是返回的data
为一个空对象
问题根因:
Map不是JSON原生支持的数据类型,序列化时会丢失其特殊结构
Map键可以是任意类型(对象、函数等),而 JSON 只支持字符串键
解决措施:
使用Object.fromEntries() 将一个键值对列表(entries)转换成一个普通对象
const dataMap = new Map<String, Array<MockAssetFormData>>dataMap.set('assetInfoList', matchAssetInfo)console.log('dataMap', dataMap)const dataObj = Object.fromEntries(dataMap)console.log('dataObj', dataObj)return {code: matchAssetInfo.length > 0 ? 300 : 404,data: dataObj,isSuccess: matchAssetInfo.length > 0,message: matchAssetInfo.length > 0 ? 'success' : 'asset not found'}
本文转成dataObj进行返回,能够正常返回Map数据
总结
mock技术把请求后端接口返回json数据调整成请求mock服务返回json数据,mock服务返回的数据一般个人或团队内部维护,能够提高开发效率、避免对外部接口的依赖阻塞开发进度。也存在一些不足:如测试数据存在局限性,不能全面反应出真实的数据、维护成本的增加,若调用外部接口调整了,相应的mock规则也需要跟着调整。