React中使用map动态渲染匹配列名的API表格数据问题
动态渲染API返回数据表格的正确实现
核心错误点
- 表头遍历逻辑里直接修改
element原数组追加字段,导致列数据被污染,出现重复/多余列 - 表体只写了单个
<td>标签,没有嵌套遍历列数组生成和列头数量一致的单元格 - 取值时用
curr[element]写法错误:element是列名数组,不是单个字段键名,无法正确取到行内对应字段的值
实现逻辑
- 不要在渲染流程中修改预定义的原列配置数组,如果需要追加
date等额外展示列,单独创建新的渲染用列数组存储配置,避免污染源数据 - 表头遍历渲染列数组,逐个生成
<th>标签 - 先遍历API返回的行数据数组生成每行的
<tr>标签,再在每行内部嵌套遍历一次渲染列数组,逐列生成<td>单元格,用当前遍历到的单个列名作为键,从行数据对象中取对应值渲染即可
代码示例
原生JS实现
// 预定义基础列,全程不修改该原数组 const baseColumns = [ "ENDURANCE", "SPEED", "AGILITY", "STRENGTH" ] // 需要展示date等额外字段时,单独拼接渲染用的列数组 const renderColumns = [...baseColumns, "date"] /** * 渲染表格 * @param {HTMLElement} tableNode 表格DOM节点 * @param {Array} rowDataList 接口返回的行数据数组 */ function renderTable(tableNode, rowDataList) { // 渲染表头 const thead = tableNode.querySelector('thead') const headerTr = document.createElement('tr') renderColumns.forEach(col => { const th = document.createElement('th') th.textContent = col headerTr.appendChild(th) }) thead.innerHTML = '' thead.appendChild(headerTr) // 渲染表体 const tbody = tableNode.querySelector('tbody') tbody.innerHTML = '' rowDataList.forEach(row => { const tr = document.createElement('tr') // 嵌套遍历列,生成和列头数量一一对应的td renderColumns.forEach(colKey => { const td = document.createElement('td') // 用当前遍历到的单个列名作为键取值,空值兜底显示横杠 td.textContent = row[colKey] ?? '-' tr.appendChild(td) }) tbody.appendChild(tr) }) } // 接口请求成功后调用渲染方法即可 // fetch('/api/data').then(res => res.json()).then(data => renderTable(document.querySelector('#dataTable'), data))
Vue模板写法示例
<template> <table id="dataTable"> <thead> <tr> <th v-for="col in renderColumns" :key="col">{{ col }}</th> </tr> </thead> <tbody> <tr v-for="row in tableData" :key="row._id"> <!-- 每行内部遍历列,生成对应数量的td --> <td v-for="col in renderColumns" :key="col"> {{ row[col] ?? '-' }} </td> </tr> </tbody> </table> </template> <script setup> import { ref, computed } from 'vue' const baseColumns = [ "ENDURANCE", "SPEED", "AGILITY", "STRENGTH" ] // 扩展展示列,不修改原baseColumns数组 const renderColumns = computed(() => [...baseColumns, 'date']) const tableData = ref([]) // 接口获取数据逻辑 // const getTableData = async () => { // const res = await fetch('/api/stat') // tableData.value = await res.json() // } // getTableData() </script>
拓展提示:如果需要给列展示中文别名,可以把列配置改成对象格式,例如
[{key: 'ENDURANCE', label: '耐力'}, {key: 'SPEED', label: '速度'}],渲染表头时取col.label作为显示文本,渲染单元格时取row[col.key]作为内容即可。
内容的提问来源于stack exchange,提问作者Mohit Rathore
相关产品推荐
相关产品推荐

