react 复杂数据的转换,把一堆从form表单获取的values一维数组的数据转换成树形结构的数据

本文介绍了如何处理从React表单获取的一维数组数据,并将其转换为树形结构,以便更好地组织和传递给后端接口。通过对数据的处理,实现了从简单数字索引到复杂树状结构的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这些数据的页面结构是这样的:

 

这些数据是从form表单的values获取的,通过数字下标可以区分有几组数据,并且区分一组数据里面又有几组二级数据

 要转成成树形结构的数据:

 所以要对values那些数据进行处理:

// 点击提交按钮时调用form表单校验函数

const handleSave = () => {
    form.validateFields().then(values => {
        const arr = Object.entries(values); // 处理values(有两层数组,把key和value拆开来了)
        // 处理arr,把key和value都存进一个数组里面
        const value = [];
        arr?.map(v => {
            const arrs = v[0]; // key
            const arrs2 = v[1]; // value
            if (arrs?.split('_')?.length > 1) {
                value.push({ key: arrs?.split('_'), value: arrs2});
            }
            return v;
        });
        // 对value进行扁平化处理
        const keyResult = value?.map(k => {
            if (k.key.length === 2) {
                const [key, panelIndex] = k.key;
                return {...k, key, panelIndex};
            } else {
                const [key, panelIndex, index] = k.key;
                return {...k, key, panelIndex, index};
            }
        });
        // 把修改后的数据放进list里面,通过遍历原来的panels即可
        const list = panels?.map(v => {
            // 拆分不同的折叠面板的数据
            const arr = keyResult.filter(item => Number(item.panelIndex) === v.key);
            // 拆分多层级表单(有index就说明是枚举值那一块的表单)
            const firstList = arr.filter(item => !item.index); // 二级表单(菜单名称,类型)
            const secondList = arr.filter(item => item.index); // 三级表单(枚举值,维度)
            // 合并对象(二级表单)
            let firstPanel = {};
            firstList.forEach(item => {
                firstPanel = { ...firstPanel, [item.key]: item.value };
            });
            // 三级表单(数量不固定,要合并对象后放入一个数组里面存起来)
            const secondPanel = [];
            // 通过index可以区分是否是同一行表单,是一行就放入一个对象里面
            _.values(_.groupBy(secondList, 'index')).forEach(itemList => {
                let data = {};
                itemList.forEach(d => {
                    data = { ...data, [d.key]: d.value, key: Number(d.index) }; // key要加上,防止保存时表单会显示空
                });
                return secondPanel.push(data);
            });
            const mergeList = { ...firstPanel, permission: [...secondPanel] }
            return { ...v, ...mergeList }
        });
        // 判断菜单名称是否重复,只要有两个是一样就判断为重复
        const dataRepeat = list.map(v => v.resourceName);
        const dataRepeat2 = [];
        dataRepeat.forEach(v => {
            if (v.indexOf('-') > -1) {
                dataRepeat2.push(v.split('-')[0]);
            } else {
                dataRepeat2.push(v);
            }
        });
        setPanels(list);
        // 传参
        const params = {
            permissionCategorys: [
                {
                    permissionCategory: values.permissionCategory,
                    resourceNames: list?.map(i => {
                        return {
                            permissionType: i.permissionType?.toString(),
                            resourceId: i.resourceName?.split('-')[1] || i.resourceId,
                            resourceName: i.resourceName?.split('-')[0],
                            permission: i.permission?.map(v => {
                                return {
                                    permissionKey: v.permissionKey,
                                    permissionValue: v.permissionValue,
                                };
                            }),
                        };
                    }),
                },
            ],
        };
        // 判断折叠面板里面的数据是否发生改变
        const data = [];
        // rowPanels是一进这个页面获取到的数据,拿来跟改变后的数据进行对比
        rowPanels?.forEach(it => {
            // 把跟params里没有的字段去掉,要保证字段的统一才能进行比较
            const { key, ...restData } = it;
            if (it.permission) {
                it.permission?.forEach(i => {
                    const { key, isCheckedValue, ...restData2 } = i;
                    data.push({
                        ...restData,
                        permission: [{ ...restData2 }],
                        permissionType: it.permissionType.join(','),
                    });
                });
            }
        });
        // loadsh里面有个isEqual可以深度比较两个数组是否相同
        const isChange = _.isEqual(params.permissionCategorys[0].resourceNames, data);
        // 判断菜单名称是否重复,利用去重,如果数量相同,则无重复,反之...
        if (dataRepeat2.length === new Set(dataRepeat2).size) {
            // 判断进这个页面是新增还是编辑,区分接口isType是上级页面传过来的字段
            if (isType === 'edit') {
                // 判断折叠面板数据是否发生变动
                if (isChange) {
                    console.log('相同,直接调编辑接口')
                } else {
                    console.log('不相同,弹框提示用户,调编辑接口')
                }
            } else {
                console.log('新增接口')
            }
        } else {
            message.error('菜单名称不能重复!')
        }
    });
}

至此,数据就处理好了,传给后端就可以正常调接口了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值