Vue+TypeScript如何正确渲染含缺失值的数据库动态透视表
动态透视表错位问题修复方案
问题根源
你的代码存在两处逻辑缺陷导致数据错位:
- 轮次(列标题)收集逻辑错误:仅提取了第一个部位(Ate)下存在的轮次,没有收集当前角色所有出现过的轮次,也未做数值排序,列的顺序和总数本身就不准确
- 单元格渲染逻辑错误:逐行渲染时遍历的是当前行自有存在值的轮次对象,缺失值的轮次不会生成空
<td>占位,直接导致后续单元格向前错位列
修复代码
不需要硬编码任何行列值,完全支持后续动态扩展,修改逻辑如下:
- 重写轮次计算属性,收集全量轮次并按数值升序排序
- 行渲染时统一遍历全量轮次数组,逐轮匹配当前行对应的值,无匹配则渲染空单元格
<script setup lang="ts"> const props = defineProps<{ data?: CharacterDetail; }>(); // 按Ate分组存储数据逻辑保留 const eats = computed(() => { if (!props.data) return {}; const d = {} as { [key: string]: { rounds: { [key: string]: any } } }; for (let x of props.data.roundlyData) { // 过滤非激活数据,可根据业务需求调整规则 if (!x.active) continue; if (!d[x.ate]) { d[x.ate] = { rounds: {} }; } d[x.ate].rounds[x.round] = x.value; } return d; }); // 修正:收集全量轮次,排序后作为统一列集合 const rounds = computed(() => { if (!props.data) return []; const roundSet = new Set<number>(); // 遍历所有数据条目收集出现过的全部轮次 props.data.roundlyData.forEach(item => { if (item.active) roundSet.add(item.round); }); // 转数组后按数值升序排序,保证列顺序固定正确 return Array.from(roundSet).sort((a,b) => a - b); }); // 可选:按固定规则排序行标题,保证行顺序稳定 const sortedAtes = computed(() => { return Object.keys(eats.value).sort(); }) </script> <template> <table class="triage-table"> <colgroup> <col style="width: 60px" /> </colgroup> <thead> <tr v-if="rounds.length"> <th></th> <th v-for="round of rounds" :key="round">{{ round }}</th> </tr> </thead> <tbody> <!-- 遍历排序后的Ate列表渲染行 --> <tr v-for="ate in sortedAtes" :key="ate"> <td>{{ ate }}</td> <!-- 遍历全局统一轮次列表逐列取值,缺失值自动留空 --> <td v-for="round in rounds" :key="round"> {{ eats[ate].rounds[round] ?? '' }} </td> </tr> </tbody> </table> </template>
效果说明
- 自动收集当前角色所有存在的轮次作为列、所有存在的部位作为行,无需硬编码
- 列默认按轮次数值升序排列,行顺序可通过修改
sortedAtes的排序逻辑自定义 - 缺失值位置自动渲染空单元格占位,不会出现值串列错位问题
- 后续新增轮次、新增部位数据时,表格会自动适配扩展,不需要修改前端代码
内容的提问来源于stack exchange,提问作者Dave F
相关产品推荐
相关产品推荐

