VueJS实现Laravel API返回JSON数据行转列展示成绩表问题咨询
Vue 实现JSON数据行转列(按NIM分组展示成绩)
核心逻辑为将接口返回的扁平成绩数据,按nim字段聚合为单个学生对象,每个对象下以id_sk1为键存储对应成绩。
Vue2 完整修改方案
1. 新增计算属性处理转置逻辑
computed:{ // 原有计算属性保留 transposedData() { const map = {} // 聚合学生基础信息与对应成绩 this.penilaian1.forEach(item => { if (!map[item.nim]) { map[item.nim] = { nim: item.nim, nama: item.nama, scores: {} } } map[item.nim].scores[item.id_sk1] = item.nilai }) // 转换为数组供模板遍历 return Object.values(map) } },
2. 修改模板渲染逻辑
<table class="table"> <thead> <tr> <th>NIM</th> <th>Nama</th> <th v-for="sk in subkriteria" :key="sk.id_sk1"> {{ sk.sub_kriteria }} </th> <th>操作</th> </tr> </thead> <tbody> <tr v-for="peserta in transposedData" :key="peserta.nim"> <td>{{ peserta.nim }}</td> <td>{{ peserta.nama }}</td> <!-- 遍历所有评分项渲染对应成绩 --> <td v-for="sk in subkriteria" :key="sk.id_sk1"> {{ peserta.scores[sk.id_sk1] || 'Tidak ada data' }} </td> <td> <div class="btn-group"> <router-link :to="{ name: 'penilaian1.show', params:{id: peserta.nim}}" class="btn btn-sm btn-outline-info">Show</router-link> </div> </td> </tr> </tbody> </table>
Vue3 完整修改方案
1. 逻辑部分调整
import axios from 'axios' import { onMounted, ref, watchEffect } from 'vue' import SideBar from './../../../components/SideBar.vue' export default { components: { SideBar, }, setup() { let penilaian1 = ref([]) let subkriteria = ref([]) let transposedData = ref([]) // 接口请求逻辑 onMounted(() => { axios.get('http://127.0.0.1:8000/api/penilaian1') .then((res) => { penilaian1.value = res.data.data }) .catch((err) => console.log(err.response)) }) onMounted(() => { axios.get('http://127.0.0.1:8000/api/penilaian1/table_sk1') .then((res) => { subkriteria.value = res.data.data }) .catch((err) => console.log(err.response)) }) // 数据变化时自动执行转置 watchEffect(() => { const map = {} penilaian1.value.forEach(item => { if (!map[item.nim]) { map[item.nim] = { nim: item.nim, nama: item.nama, scores: {} } } map[item.nim].scores[item.id_sk1] = item.nilai }) transposedData.value = Object.values(map) }) return { transposedData, subkriteria } }, }
2. 模板部分调整
<thead class="bg-gray-100 dark:bg-gray-700"> <tr> <th scope="col" class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> NIM </th> <th scope="col" class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> Nama </th> <!-- 渲染评分项表头 --> <th v-for="sk in subkriteria" :key="sk.id_sk1" scope="col" class="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400"> {{ sk.sub_kriteria }} </th> <th scope="col" class="relative px-6 py-3"> <span class="sr-only">操作</span> </th> </tr> </thead> <tbody> <tr v-for="peserta in transposedData" :key="peserta.nim" class="bg-white border-b dark:bg-gray-800 dark:border-gray-600" > <td class="px-6 py-4 text-sm font-medium text-gray-900 whitespace-nowrap dark:text-white"> {{ peserta.nim }} </td> <td class="px-6 py-4 text-sm text-gray-500 whitespace-nowrap dark:text-gray-400"> {{ peserta.nama }} </td> <!-- 渲染对应成绩 --> <td v-for="sk in subkriteria" :key="sk.id_sk1" class="px-6 py-4 text-sm text-gray-500 whitespace-nowrap dark:text-gray-400"> {{ peserta.scores[sk.id_sk1] || 'Tidak ada data' }} </td> <td class="px-6 py-4 text-sm font-medium text-right whitespace-nowrap"> <!-- 自行补充操作按钮逻辑 --> </td> </tr> </tbody>
内容的提问来源于stack exchange,提问作者NorthernOsprey
相关产品推荐
相关产品推荐

