前言
kk-utils 是一款我自己基于这几年开发封装出来的前端工具库
bidirectional-mapping
bidirectional-mapping是kk-utils里的工具之一,其作用是键值对双向映射
它可以把一个字符串、数字、对象、数组按我们的映射规则进行转换
BiMap
用来生成映射规则的一个工具
BiMapConversion
用来把目标数据转换成映射规则处理后的数据
使用方法
安装
npm install kk-utils-library -S
pnpm add kk-utils-library -S
编写映射规则
const map = new BiMap([
["a", "A"], // 把'a'转成'A',也可以反过来把'A'转成'a'
[
"b",
"B",
{
transformType: String, // 把键名对应的value进行处理,比如转成字符串,转成数字,转成Boolean
},
],
[
"c",
"C", // 数组嵌套数组表示c是复杂对象,里面的数据还要继续转换,c.d会变成C.D
[
[
"d",
"D",
{
transformSourceType: "object", // 转换数据的类型 object、map、array
transformType: Number,
transformInverted: true, // 是否可以反过来转换 如为true就会把原本值为'否'变成0
transform: {
0: "否",
1: "是",
},
},
],
[
"e",
"E",
{
transformType: Boolean,
},
],
[
"f",
"F",
[
[
"g",
"G",
{
transformSourceType: "map",
transformType: Number,
transformInverted: true,
transform: new Map([
[0, "zero"],
[1, "one"],
]),
},
],
[
"h",
"H",
{
transformSourceType: "array",
transformType: Number,
transformInverted: true,
transformLabelKey: "label",
transformValueKey: "value",
transform: [
{
label: "否",
value: 0,
},
{
label: "是",
value: 1,
},
],
},
],
],
],
],
],
[
"children",
"CHILDREN",
{
recursion: true, // 树结构 递归处理
},
],
[
"k",
"K",
new BiMap([
[0, "零"],
[1, "一"],
]), // 深层对象映射可以使用数组嵌套也可以直接使用BiMap BiMap可以处理键名转换也可以处理值的转换
],
]);
转换数据
写一个测试数据
const data = [
{
a: 1,
b: 1,
c: {
d: 1,
e: 1,
f: [
{
g: 1,
h: 1,
},
],
},
children: [
{
a: 0,
b: 0,
c: {
d: 0,
e: 0,
f: [
{
g: 0,
h: 0,
},
],
},
k: 0,
},
{
a: 1,
b: 1,
c: {
d: 1,
e: 1,
f: [
{
g: 1,
h: 1,
},
],
},
k: 1,
},
],
k: 1,
},
];
使用映射规则转换数据
const mapData = BiMapConversion(data, map);
console.log(mapData)
转换结果
[
{
"A": 1,
"B": "1",
"C": {
"D": "是",
"E": true,
"F": [
{
"G": "one",
"H": "是"
}
]
},
"CHILDREN": [
{
"A": 0,
"B": "0",
"C": {
"D": "否",
"E": false,
"F": [
{
"G": "zero",
"H": "否"
}
]
},
"K": "零"
},
{
"A": 1,
"B": "1",
"C": {
"D": "是",
"E": true,
"F": [
{
"G": "one",
"H": "是"
}
]
},
"K": "一"
}
],
"K": "一"
}
]
截图对比

可以看到测试数据已经按我定义好的映射规则进行了转换,无论是键名还是值,都转换成功了的
融入业务使用
比如和后端对接接口的时候,后端键名不规范,我们写逻辑的时候就要去重新命名,多处用同一接口的话,就要到处维护,不方便。再比如同一个字段的值一会是字符串,一会是数字,就会对我们的逻辑代码造成不易擦觉得影响,所以可以使用这个工具在接口处统一做出入数据管理
在接口处统一做出入数据管理
比如我要对接后端的反馈接口的CURD
定义公共分页映射
// src/constants/bi-map/common/pagination/index.js
import { BiMap } from 'kk-utils-library/bidirectional-mapping';
// 分页参数
export const $paginationReqItemMap = new BiMap([
[
'pagination',
'pagination',
[
['page', 'pageNumber'],
['pageSize', 'pageSize']
]
]
]);
定义接口映射
// src/constants/bi-map/feedback/index.js
import { BiMap } from 'kk-utils-library/bidirectional-mapping';
import { $paginationReqItemMap } from '../common/pagination';
// 意见反馈列表
export const $feedbackListReqItemMap = new BiMap([
['id', 'id'], // ID
['type', 'emergencyDegreeType'], // 紧急程度类型
['topic', 'theme'], // 主题
['content', 'content'] // 内容
]);
export const $feedbackListResItemMap = new BiMap([
['id', 'id'], // ID
['type', 'emergencyDegreeType'], // 紧急程度类型
['topic', 'theme'], // 主题
['content', 'content'] // 内容
]);
// 意见反馈分页
export const $feedbackPageReqItemMap = new BiMap([
...$feedbackListReqItemMap.sourceData, // 复用 避免多次定义
...$paginationReqItemMap.sourceData // 复用 避免多次定义
]);
export const $feedbackPageResItemMap = $feedbackListResItemMap; // 相同映射规则直接指向共用
// 意见反馈详情
export const $feedbackDetailReqItemMap = new BiMap([['id', 'id']]);
export const $feedbackDetailResItemMap = $feedbackListResItemMap;
// 意见反馈新建
export const $feedbackCreateReqItemMap = $feedbackListReqItemMap;
export const $feedbackCreateResItemMap = new BiMap([]);
// 意见反馈编辑
export const $feedbackUpdateReqItemMap = $feedbackListReqItemMap;
export const $feedbackUpdateResItemMap = new BiMap([]);
// 意见反馈删除
export const $feedbackDeleteReqItemMap = new BiMap([['id', 'id']]);
export const $feedbackDeleteResItemMap = new BiMap([]);
接口处使用映射做出入口参数管理
// src/apis/feedback/index.js
import { BiMapConversion } from 'kk-utils-library/bidirectional-mapping';
import {
$feedbackCreateReqItemMap,
$feedbackCreateResItemMap,
$feedbackDeleteReqItemMap,
$feedbackDeleteResItemMap,
$feedbackDetailReqItemMap,
$feedbackDetailResItemMap,
$feedbackListReqItemMap,
$feedbackListResItemMap,
$feedbackPageReqItemMap,
$feedbackPageResItemMap,
$feedbackUpdateReqItemMap,
$feedbackUpdateResItemMap
} from '@/constants/bi-map/feedback';
// 分页获取意见反馈
export function getFeedbackPage(Service) {
return (params) =>
new Promise((resolve, reject) => {
params = BiMapConversion(params || {}, $feedbackPageReqItemMap);
Service.get('/api/feedbacks', params)
.then((res) => {
res.data = BiMapConversion(res.data || {}, $feedbackPageResItemMap);
resolve(res);
})
.catch((error) => reject(error));
});
}
// 获取意见反馈列表
export function getFeedbackList(Service) {
return (params) =>
new Promise((resolve, reject) => {
params = BiMapConversion(params || {}, $feedbackListReqItemMap);
Service.get('/api/feedbacks/list', params)
.then((res) => {
res.data = BiMapConversion(res.data || [], $feedbackListResItemMap);
resolve(res);
})
.catch((error) => reject(error));
});
}
// 查询意见反馈详情
export function getFeedbackDetail(Service) {
return (params) =>
new Promise((resolve, reject) => {
params = BiMapConversion(params || {}, $feedbackDetailReqItemMap);
Service.get(`/api/feedbacks/${params.id}`, { ...params, populate: '*' })
.then((res) => {
res.data = BiMapConversion(res.data || {}, $feedbackDetailResItemMap);
resolve(res);
})
.catch((error) => reject(error));
});
}
// 新建意见反馈
export function createFeedback(Service) {
return (params) =>
new Promise((resolve, reject) => {
params = BiMapConversion(params || {}, $feedbackCreateReqItemMap);
Service.post('/api/feedbacks', { data: params })
.then((res) => {
res.data = BiMapConversion(res.data || {}, $feedbackCreateResItemMap);
resolve(res);
})
.catch((error) => reject(error));
});
}
// 更新意见反馈
export function updateFeedback(Service) {
return (params) =>
new Promise((resolve, reject) => {
params = BiMapConversion(params || {}, $feedbackUpdateReqItemMap);
Service.put(`/api/feedbacks/${params.id}`, { data: params })
.then((res) => {
res.data = BiMapConversion(res.data || {}, $feedbackUpdateResItemMap);
resolve(res);
})
.catch((error) => reject(error));
});
}
// 删除意见反馈
export function deleteFeedback(Service) {
return (params) =>
new Promise((resolve, reject) => {
params = BiMapConversion(params || {}, $feedbackDeleteReqItemMap);
Service.delete(`/api/feedbacks/${params.id}`, params)
.then((res) => {
res.data = BiMapConversion(res.data || {}, $feedbackDeleteResItemMap);
resolve(res);
})
.catch((error) => reject(error));
});
}
这样只需要在接口封装处对params出参做映射转换和接收到数据时对res里的data做映射转换,我们就可以在项目里直接使用自己定义的key,出参给后台的时候也会反过来把我们的key根据映射规则转成后台原本的key再传递给后台的
其他
除了以上业务使用,我们还能用来对单个数据处理
// 我们用回上面定义的new BiMap
const mapping_a = map.get('A') // a
const mapping_A = map.get('a') // A