如何使用Vue.js结合API数据创建含合并单元格的嵌套表格?
问题描述
我从API获取了如下格式的数据:
{ "fiscal_year": "2023", "quarter": "FY23 - Q1", "A": 157, "B": 122, "C": 392, "A_yoy": 0.4, "B_yoy": 0.008, "C_yoy": 0.21 }
我需要创建一个类似图片中的Vue.js表格,但不确定如何对数据进行结构化以实现表格中的效果。以下是我目前编写的代码:
const structuredItems = {}; const Quarters = new Set(); self.dataFQMIssues.forEach(entry => { const { fiscal_year, quarter, A, B, C, D, E, F }; Quarters.add(quarter); if (!structuredItems[fiscal_year]) { structuredItems[fiscal_year] = [ { label: 'Open', items: [] }, { label: 'Execution', items: [] } ]; } structuredItems[fiscal_year][0].items.push({ item: 'A', value: A }); structuredItems[fiscal_year][1].items.push({ item: 'E', value: E }); }); self.dataItem = structuredItems; self.quarters = Array.from(Quarters);
修正后的结构化方案
你当前代码存在几个问题:解构语句语法错误、未处理同比数据、原API返回字段里没有D/E/F却进行了解构。下面是适配需求的修正方案:
const structuredItems = {}; const quarters = new Set(); // 定义指标与分类的对应关系,可根据表格需求调整 const indicatorGroups = { 'Open': ['A'], 'Execution': ['B', 'C'] }; self.dataFQMIssues.forEach(entry => { // 只解构API实际返回的字段 const { fiscal_year, quarter, A, B, C, A_yoy, B_yoy, C_yoy } = entry; quarters.add(quarter); // 初始化当前年份的结构 if (!structuredItems[fiscal_year]) { structuredItems[fiscal_year] = Object.entries(indicatorGroups).map(([label, indicators]) => ({ label, items: indicators.map(indicator => ({ name: indicator, // 按季度存储数值和同比数据 quarterlyData: {} })) })); } // 填充当前季度的指标数据 structuredItems[fiscal_year].forEach(group => { group.items.forEach(item => { item.quarterlyData[quarter] = { value: entry[item.name], yoy: entry[`${item.name}_yoy`] }; }); }); }); self.dataItem = structuredItems; // 对季度排序,保证表格列顺序正确 self.quarters = Array.from(quarters).sort();
Vue表格渲染示例
基于上面的结构化数据,你可以这样编写Vue模板来生成目标表格:
<template> <div class="year-group" v-for="(groups, year) in dataItem" :key="year"> <h3>{{ year }}</h3> <table class="data-table"> <thead> <tr> <th>指标分类</th> <th>指标名称</th> <th v-for="quarter in quarters" :key="quarter">{{ quarter }}</th> </tr> </thead> <tbody> <template v-for="group in groups" :key="group.label"> <tr v-for="(item, idx) in group.items" :key="item.name"> <!-- 分类单元格跨行展示 --> <td v-if="idx === 0" :rowspan="group.items.length">{{ group.label }}</td> <td>{{ item.name }}</td> <td v-for="quarter in quarters" :key="quarter"> <div class="value">{{ item.quarterlyData[quarter]?.value }}</div> <div class="yoy" v-if="item.quarterlyData[quarter]?.yoy !== undefined"> 同比 {{ (item.quarterlyData[quarter].yoy * 100).toFixed(1) }}% </div> </td> </tr> </template> </tbody> </table> </div> </template> <style scoped> .year-group { margin-bottom: 24px; } .data-table { width: 100%; border-collapse: collapse; } th, td { border: 1px solid #e5e7eb; padding: 8px 12px; text-align: left; } .yoy { font-size: 0.85em; color: #6b7280; margin-top: 4px; } </style>
内容的提问来源于stack exchange,提问作者WBayoomi
相关产品推荐
相关产品推荐

