动态列表的数据渲染、新增、编辑等功能开发及数据处理

说一个比较繁琐的功能吧,我使用的是 vue + element UI + vxe-table 来实现的这个动态列表,其实呢 vxe-table 这个表格插件里边有动态表格 vxe-grid 只需要通过表头数组里边的 field: 'name', 与表体数组里的 name: 'Test1', 对应上就行了,很简单吧;可是问题来了,后端给我的是一串超长的id,表体里也是给了一个超长的id让进行匹配(如:图1),然后导致匹配出现问题,搜了一下说纯数字不太行,会出问题,事实也确实如此,无论怎么匹配,页面只显示有多少行数据,但每一列的值都是空的,没有任何显示,于是就自己进行了数据的处理。

图1

注:根据上图会看到表体数组 rowsList 里边又是一个数组,里边这个数组里又包含了多个对象(这多个对象就是每一列对应的值了,需要用 fieId 去匹配)

html模版部分:

html 复制代码
<vxe-grid border resizable ref="xGrid" :columns="tableColumn" :data="tableData">
    <template v-slot:operation="{ row }">
        <el-button size="mini" @click="editBtn(row)" type="text">编辑</el-button>
        <el-button size="mini" @click="delBtn(row)" type="text" style="color: #f56c6c;">删除</el-button>
    </template>
</vxe-grid>

1、对接口获取到的数据进行匹配处理,然后回显到列表上,如下:

表头数据(模拟):

javascript 复制代码
let columnList = [
    {
        "fieId": "1909122684954550274",
        "title": "JST TPM",
        "fieldType": 4
    },
    {
        "fieId": "1909122684954550275",
        "title": "备注",
        "fieldType": 0
    },
    {
        "fieId": "1909122684962938882",
        "title": "客户提出人姓名",
        "fieldType": 0
    },
    {
        "fieId": "1909122684962938883",
        "title": "提出时间",
        "fieldType": 3
    },
    {
        "fieId": "1909122684962938884",
        "title": "客户需求明细",
        "fieldType": 1
    },
    {
        "fieId": "1909122684962938885",
        "title": "功能模块名称",
        "fieldType": 0
    }
]

表体数据(模拟):

javascript 复制代码
let rowsList = [
    [
        {
            "sortNo": "0",
            "fieId": "1909122684954550274",
            "fieValue": "111"
        },
        {
            "sortNo": "0",
            "fieId": "1909122684954550275",
            "fieValue": "2132"
        },
        {
            "sortNo": "0",
            "fieId": "1909122684962938882",
            "fieValue": "4124"
        },
        {
            "sortNo": "0",
            "fieId": "1909122684962938883",
            "fieValue": "2025-04-16 00:00:00"
        },
        {
            "sortNo": "0",
            "fieId": "1909122684962938884",
            "fieValue": "1"
        },
        {
            "sortNo": "0",
            "fieId": "1909122684962938885",
            "fieValue": "发送方"
        }
    ],
    [
        {
            "sortNo": "1",
            "fieId": "1909122684954550274",
            "fieValue": "139850429"
        },
        {
            "sortNo": "1",
            "fieId": "1909122684954550275",
            "fieValue": "12312"
        },
        {
            "sortNo": "1",
            "fieId": "1909122684962938882",
            "fieValue": "312312"
        },
        {
            "sortNo": "1",
            "fieId": "1909122684962938883",
            "fieValue": "2025-04-22 00:00:00"
        },
        {
            "sortNo": "1",
            "fieId": "1909122684962938884",
            "fieValue": "1"
        },
        {
            "sortNo": "1",
            "fieId": "1909122684962938885",
            "fieValue": "213124"
        }
    ]
]

处理方法:

javascript 复制代码
                columnList.forEach((item, index) => {
                        // 为每列添加唯一field标识
                        const fieldName = `title${index}`;
                        this.$set(item, 'field', fieldName);
                        this.tableColumn.push(item);
                        
                        // 处理行数据
                        rowsList.forEach((row, rowIndex) => {
                            row.forEach((cell) => {
                                if (item.fieId === cell.fieId) {
                                    // 初始化行对象(如果尚未存在)
                                    if (!tableList[rowIndex]) {
                                        tableList[rowIndex] = {
                                            // 基础信息
                                            id: rowIndex, // 添加行ID
                                            sortNo: cell.sortNo, // 添加编号
                                        };
                                    }
                                    // 添加动态字段
                                    this.$set(tableList[rowIndex], fieldName, cell.fieValue);
                                    // 保留原始数据(可选)
                                    this.$set(tableList[rowIndex], `${fieldName}_meta`, {
                                        fieId: item.fieId,
                                        title: item.title,
                                        fieldType: item.fieldType,
                                        content: cell.fieValue,
                                    });
                                }
                            });
                        });
                    });
                    this.tableData = tableList;
                    this.tableColumn.push(
                        { type: 'seq', fixed: "left", width: 50 },
                        { title: '操作', width: 100, showOverflow: true, fixed: "right", slots: { default: 'operation' } }
                    )
                console.log(this.tableColumn,'this.tableColumn');
                console.log(this.tableData,'this.tableData');

处理后的结果数据:

以上就对列表回显处理完成!

2、接下来是新增时候的处理

javascript 复制代码
        addBtn(){
            this.dialogVisible = true;
            this.titleText = '新增';
            this.tableColumn.map((item) => {
                item.manageId = this.queryData.id,
                this.$set(item, 'content', '');
            })
        },

新增直接在 this.tableColumn 里边新增一个content 字段 然后在提交的时候直接把 this.tableColumn 这个数组全部提交给后端即可!

3、编辑处理

javascript 复制代码
        editBtn(row){
            this.dialogVisible = true;
            this.titleText = '编辑';
            this.tableColumn.forEach(item => {
                if (!item.fieId) return; // 跳过没有 fieId 的,比如操作列等
                // 在 obj1 中查找所有带有 _meta 的键
                for (const key in row) {
                    if (key.endsWith('_meta')) {
                        const meta = row[key];
                        if (meta && meta.fieId === item.fieId) {
                            this.$set(item, 'content', meta.content);
                            break;
                        }
                    }
                }
            });
        },

注:因为在列表的时候修改了数据格式,所以在编辑的时候还要对数据进行处理,然后才能使用

编辑的处理方法说明:

  • row 中的 title0_meta, title1_meta 是动态的,不能直接写死去访问。

  • 所以用 for...in 遍历 row 所有键,找到以 _meta 结尾的。

  • 然后对比 meta.fieId 与 item.fieId,如果匹配,就把 content 写入到 item.content。

附加:如果列表中有人员、组织、类型等字段需要通过id去匹配显示中文的,方法如下(我的是通过人员id匹配人员姓名展示):

修改 getList 方法

javascript 复制代码
getList() {
    this.loading = true;
    this.tableColumn = [];
    this.tableData = [];
    let tableList = [];
    let userIdList = []; // 新增:收集用户ID
    let userFieldMap = []; // 保存在哪些字段上用到用户信息

    let params = {
        manageId: this.queryData.id,
        current: this.tablePage.current,
        size: this.tablePage.size,
    };

    api.queryParticularsDataAttach(params).then((res) => {
        if (res.data.data == null) {
            this.tableColumn = [];
            this.tableData = [];
        } else {
            let columnList = res.data.data.columns;
            let rowsList = res.data.data.rowsList;
            this.tablePage.totalElements = res.data.data.total;

            columnList.forEach((item, index) => {
                const fieldName = `title${index}`;
                this.$set(item, 'field', fieldName);
                this.tableColumn.push(item);

                rowsList.forEach((row, rowIndex) => {
                    row.forEach((cell) => {
                        if (item.fieId === cell.fieId) {
                            if (!tableList[rowIndex]) {
                                tableList[rowIndex] = {
                                    id: rowIndex,
                                    sortNo: cell.sortNo,
                                };
                            }

                            // 动态字段赋值
                            this.$set(tableList[rowIndex], fieldName, cell.fieValue);
                            this.$set(tableList[rowIndex], `${fieldName}_meta`, {
                                fieId: item.fieId,
                                title: item.title,
                                fieldType: item.fieldType,
                                content: cell.fieValue,
                            });

                            // 如果是人员类型字段(fieldType === 4),收集 userId
                            if (item.fieldType === 4 && cell.fieValue) {
                                userIdList.push(cell.fieValue);
                                userFieldMap.push({
                                    rowIndex,
                                    fieldName,
                                    userId: cell.fieValue,
                                });
                            }
                        }
                    });
                });
            });

            this.tableData = tableList;

            // 插入序号列和操作列
            this.tableColumn.push(
                { type: 'seq', fixed: "left", width: 50 },
                { title: '操作', width: 100, showOverflow: true, fixed: "right", slots: { default: 'operation' } }
            );

            // 👇 去查人员名称
            if (userIdList.length > 0) {
                this.getUsersList(userIdList).then((userMap) => {
                    // 替换tableData中的字段内容为用户姓名
                    userFieldMap.forEach(({ rowIndex, fieldName, userId }) => {
                        const user = userMap[userId];
                        if (user) {
                            // 替换显示值
                            this.$set(this.tableData[rowIndex], fieldName, user.realName + '(' + user.account + ')');
                            // 同步 meta 中的 content 也更新为姓名
                            if (this.tableData[rowIndex][`${fieldName}_meta`]) {
                                this.tableData[rowIndex][`${fieldName}_meta`].content = user.realName + '(' + user.account + ')';
                            }
                        }
                    });
                });
            }
        }

        this.loading = false;
    }).catch(() => {
        this.loading = false;
    });
},

// 👇 获取人员数据的方法:返回 userId -> user 信息的映射
getUsersList(idList) {
    return api.getPeoples(idList).then((res) => {
        const userList = res.data.data || [];
        const userMap = {};
        userList.forEach(user => {
            userMap[user.id] = user;
        });
        return userMap;
    });
}

以上仅是个人实现的使用方法,可根据自己的需求进行修改或者优化

至此完成!!!

测试有效!!!感谢支持!!!

相关推荐
卸任16 小时前
Vibe coding工具使用心得
前端·ai编程
brien917 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance17 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M17 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写17 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李17 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易18 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
清晨Coding18 小时前
删了 Cookie 还能自动登录?Google系网站登录态自动恢复的原理分析
javascript
风骏时光牛马18 小时前
前沿视界
前端
kyriewen18 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员