前端开发实践与后端开发解耦(一)-- 接口数据mock和接口字段映射

摘要

众所周知,现在的前后端开发都是独立的,除了一些老项目。但是如果公司的开发流程不规范就可能出现前端开发的阻塞,或者出现得多做一些无用功。正确的开发流程应该是:需求评审--需求确认--后端接口设计并输出文档 -- 前/后端开发 -- 联调 -- 测试 -- 上线 。这里主要强调优先输出接口设计文档的重要性。

Mock 数据

mock数据的作用是让前端开发不依赖后端的开发进度,减少创建数据的时间,减少联调的时间。但是mock也有自己的局限,对于一些复杂的接口没法很好的兼容,对于下载文件也不太好mock等。下面用 vue3 + vite 举例

安装依赖

npm install vite-plugin-mock -D

配置

src 目录的同级上新建mock文件夹;并在 vite.config.jsplugins 中添加下面配置,联调时将选项中的 enable 设置为 false

javascript 复制代码
// mock/index.js -- 按模块导入方便管理
import user from './user'
import data from './data'

export default [...user, ...data]


// vite.config.js
viteMockServe({
	mockPath: path.resolve(__dirname, '../../mock'),
	// enable: false,
	localEnabled: viteEnv.VITE_APP_ENV === 'development',
	watchFiles: true,
})
如何Mock数据

如何使用的官方文档:
vite-plugin-mock配置中文文档
mock数据如何使用

下面写一些常用的写法,以及对于 Restful Api 该如何通过 mock 的接口拦截;其他的使用请看文档。

说明一下Restful Api 类型的接口:

删除:/api/v1/project/:id 请求方法为: Delete

修改:/api/v1/project/:id 请求方法为: Post

详情:/api/v1/project/:id 请求方法为: Get

某个项目里的其他列表:/api/v1/project/:id/other/list 请求方法为: Get

第一种:非 Restful Api
javascript 复制代码
[
	{
		url: '/dev-api/api/v1/project',
		method: 'get',
		response: () => {
			return Mock.mock({
				code: 0,
				msg: 'OK',
				'data|10': [
					{
						id: '@guid',
						name: '@string',
						desc: '@sentence',
						created_at: '@integer(1693904305000, 1725526705000)',
					},
				],
			})
		},
	},
	// 有查询参数,以下所有都是通用的
	{
		url: '/dev-api/api/v1/project/type/list',
		method: 'get',
		response: ({ query }) => {
			const { ... } = query
			let list = ['default']
			// 根据条件生成list

			return {
				code: 0,
				msg: 'OK',
				data: {
					list,
					total: 2,
				},
			}
		},
	},
]
第二种: Restful Api/api/v1/project/:id,接口参数在后面
javascript 复制代码
[
	{
		url: /\/dev-api\/api\/v1\/project\/*/,
		method: 'delete',
		response: () => {
			return {
				code: 0,
				msg: 'OK',
				data: null,
			}
		},
	},
]
第三种: Restful Api/api/v1/project/:id/other/list,接口参数在中间
javascript 复制代码
	{
		url: /\/dev-api\/api\/v1\/project\/[^/]+\/other\/list/,
		method: 'get',
		response: () => {
			return {
				code: 0,
				msg: 'OK',
				data: Mock.mock({
					id: '@guid',
					name: '@string',
				}),
			}
		},
	}

接口字段映射

在我们写表单,写表格时都会绑定一个 prop 属性的值,该值对应的就是后端接口返回的 字段名;传参数时也是后端需要什么前端传什么,如果后端需要的时下划线的参数 project_name,安装前端的代码习惯都是 驼峰命名 的参数名,这时候你可以将驼峰转下划线。这里说一下更好的实践,那就是这一节的主题:接口字段的映射。将后端接口的响应数据,传给后端的请求参数,通过字段映射转换成前端需要的字段名和后端需要的参数名。

实现

src 中新建 field-map 文件夹,按模块新增对应的文件,比如 project.js。下面是具体代码

javascript 复制代码
import { mapRequestFields, formatDate } from '@/utils/common'

export const fieldMap = {
	name: 'name',
	description: 'description',
	creator: 'creator',
	createdAt: 'created_at',
}

// Format project list
export function formatList(data) {
	return (
		data?.map(item => ({
			id: item.id,
			name: item.name,
			description: item.description,
			creator: item.creator,
			createdAt: formatDate(item.created_at),
		})) || []
	)
}

export function formatQuery(params) {
	return mapRequestFields(params, fieldMap)
}
对象类型字段转换的翻转

如果需要将后端的响应对象转换成前端需要的字段名,或者在表格排序时需要将字段转换回去,可以通过下面的方式实现。其他更多的需求可以自己拓展

javascript 复制代码
export const fieldMapReverse = Object.keys(fieldMap).reduce((acc, key) => {
	acc[fieldMap[key]] = key
	return acc
}, {})

export function formatQuery(params) {
	return mapRequestFields(params, fieldMapReverse )
}
mapRequestFields的实现,对请求参数进行转换
javascript 复制代码
// 未实现嵌套的转换
export function mapRequestFields(obj, map) {
	const isFormData = obj instanceof FormData
	const mapFields = isFormData ? new FormData() : {}

	if (isFormData) {
		for (const [key, value] of obj.entries()) {
			if (value === 'undefined' || value === null || value === '') return
			const newKey = map[key] || key
			mapFields.append(newKey, value)
		}
	} else {
		Object.keys(obj).forEach(key => {
			if (obj[key] === 'undefined' || obj[key] === null || obj[key] === '') return
			const newKey = map[key] || key
			mapFields[newKey] = obj[key]
		})
	}

	return mapFields
}
相关推荐
沉默璇年44 分钟前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder1 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727571 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
SoaringHeart1 小时前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter
会发光的猪。2 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
天下代码客2 小时前
【vue】vue中.sync修饰符如何使用--详细代码对比
前端·javascript·vue.js
猫爪笔记2 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
前端李易安2 小时前
Webpack 热更新(HMR)详解:原理与实现
前端·webpack·node.js
红绿鲤鱼2 小时前
React-自定义Hook与逻辑共享
前端·react.js·前端框架
周全全2 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php