1.0.2 • Published 2 months ago
@wx_1098/object-mapper v1.0.2
Object Mapper 使用指南(优化版)
🎯 快速入门
1. 安装与基础概念
对象映射是将一个对象的属性按照规则转换到另一个对象的过程。适用于:
- 数据转换 :当你需要将一种数据结构转换为另一种数据结构时,比如将后端返回的数据格式转换为前端组件需要的格式。
- 对象克隆 :需要创建一个对象的副本,但又不想手动复制每个属性时。
- 数据整合 :将多个对象的数据整合到一个新的对象中。
- API 数据处理 :处理不同 API 返回的数据格式,使其符合你的应用需求。
npm install @wx_1098/object-mapper
// 初始化映射器
import { ObjectMapper, Transformers } from '@wx_1098/object-mapper';
const mapper = new ObjectMapper();
2. 最简示例
const user = { name: '小明', age: 18 };
// 基础映射规则(字符串简写)
const result = mapper.map(user, [
'username:name', // 将源.name映射到目标.username
'age' // 同名属性直接映射
]);
/* 结果:
{ username: "小明", age: 18 } */
🧭 核心功能详解
3. 路径语法
支持点分隔符与数组格式两种路径写法:
// 点分隔写法(自动拆分为数组)
mapper.map(data, ['a.b.c']);
// 数组写法(直接使用路径段)
mapper.map(data, [{ target: ['x', 'y', 'z'] }]);
// 混合写法(处理特殊字符)
const data = { 'user.id': 123 };
mapper.map(data, [{ target: 'userId', source: ['user.id'] }]);
4. 嵌套结构处理
const order = {
customer: {
name: '小明',
address: {
city: '北京'
}
}
};
mapper.map(order, ['clientName:customer.name', 'location:customer.address.city']);
/* 结果:
{
clientName: "小明",
location: "北京"
} */
5. 自动创建嵌套结构
mapper.map({ value: 100 }, ['a.b.c.value']);
/* 自动创建缺失结构:
{
a: {
b: {
c: {
value: 100
}
}
}
} */
🛠️ 进阶功能
6. 值转换管道
使用内置转换器或自定义函数处理值:
const product = { price: '199.99' };
mapper.map(product, [
{
target: 'price',
transform: [
Transformers.string.trim, // 去空格
(val) => parseFloat(val), // 转数字
Transformers.number.currency('¥') // 格式化为货币
]
}
]);
/* 结果:{ price: "¥200.00" } */
7. 条件映射
const data = { role: 'admin', score: 85 };
mapper.map(data, [
{
target: 'accessLevel',
when: (ctx) => ctx.source.role === 'admin' // 仅当role为admin时映射
},
{
target: 'grade',
when: (ctx) => ctx.value >= 60, // 使用转换后的值判断
transform: (score) => (score >= 90 ? 'A' : 'B')
}
]);
/* 结果:{ accessLevel: "admin", grade: "B" } */
⚙️ 配置策略
8. 全局配置
const customMapper = new ObjectMapper({
strict: true, // 严格模式(路径不存在时报错)
nullPolicy: 'ignore', // 忽略空值
autoType: true // 自动类型转换
});
9. 局部配置覆盖
mapper.map(data, [
{
target: 'specialField',
config: {
strict: false // 仅对本规则生效
}
}
]);
🧩 插件系统
10. 开发日志插件
const loggerPlugin = {
beforeMap: (ctx) => console.log('开始映射:', ctx.source),
afterRule: (ctx) => console.log(`处理规则: ${ctx.rule.targetPath}`),
onError: (err) => console.error('发生错误:', err)
};
mapper.use(loggerPlugin);
11. 错误处理插件
const errorHandler = {
onError: (error, ctx) => {
alert(`映射错误: ${error.message}`);
return false; // 阻止错误抛出
}
};
mapper.use(errorHandler);
🏆 最佳实践
场景 1:API 响应处理
// 原始API数据结构
const apiResponse = {
user_info: {
full_name: '王小明',
contacts: [{ type: 'email', value: 'xm@example.com' }]
}
};
// 转换规则
mapper.map(apiResponse, [
'user.name:user_info.full_name',
{
target: 'user.email',
source: 'user_info.contacts',
transform: (contacts) => contacts.find((c) => c.type === 'email')?.value || ''
}
]);
/* 结果:
{
user: {
name: "王小明",
email: "xm@example.com"
}
} */
场景 2:数据库模型转换
// 数据库原始数据
const dbRow = {
id: 1,
created_at: '2023-05-20T08:00:00Z',
price_cents: 2999
};
// 转换规则
mapper.map(dbRow, [
'productId:id',
{
target: 'price',
source: 'price_cents',
transform: (cents) => (cents / 100).toFixed(2)
},
{
target: 'createdAt',
transform: [Transformers.date.toISO]
}
]);
/* 结果:
{
productId: 1,
price: "29.99",
createdAt: "2023-05-20T08:00:00.000Z"
} */
⚠️ 重要注意事项
路径解析规则
items.0.name
→ 解析为数组索引items[0].name
→ 解析为对象属性- 空路径段会被自动忽略(
a..b
→['a','b']
)
性能优化
// 启用路径缓存(默认关闭) new ObjectMapper({ cachePaths: true }); // 预编译常用规则 const commonRules = mapper.normalizeRules(myRules);
调试技巧
// 查看标准化后的规则 console.log(mapper.normalizeRules(['a.b.c'])); // 使用调试插件 mapper.use({ beforeRule: (ctx) => console.log('当前值:', ctx.value) });
📚 学习路径建议
新手阶段
- 掌握基础属性映射
- 理解路径解析规则
- 尝试简单值转换
进阶阶段
- 学习条件映射策略
- 掌握嵌套结构处理
- 配置全局/局部策略
专家阶段
- 开发自定义插件
- 实现复杂类型转换
- 优化映射性能
通过本指南,您将能:
- ✅ 处理各种数据结构转换
- ✅ 实现智能条件映射
- ✅ 开发定制化插件
- ✅ 优化映射器性能
- ✅ 应对复杂业务场景