【问题标题】:VueJS transpose table row to column from JSON dataVueJS 将表行从 JSON 数据转置为列
【发布时间】:2021-11-20 14:21:40
【问题描述】:

所以我有来自 Laravel API(由 Axios 调用)的 JSON 数据,我想转置:

{"message":"Data peserta tahap 1 OR XI","data":[
{"nim":1810112048,"nama":"Annisa indra","id_sk1":11,"nilai":30},
{"nim":1810112048,"nama":"Annisa indra","id_sk1":12,"nilai":30},
{"nim":1810112048,"nama":"Annisa indra","id_sk1":13,"nilai":25},
{"nim":1810112048,"nama":"Annisa indra","id_sk1":21,"nilai":72},
{"nim":1810112048,"nama":"Annisa indra","id_sk1":31,"nilai":57},
{"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":11,"nilai":20},
{"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":12,"nilai":20},
{"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":13,"nilai":10},
{"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":21,"nilai":75},
{"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":31,"nilai":57}
]}
有5个重复的NIM,内容不同nilai(等级)

这是我的目标:

+------------+------------------------+----+----+----+----+----+
|    nim     |         nama           | 11 | 12 | 13 | 21 | 31 |
+------------+------------------------+----+----+----+----+----+
| 1810112048 | Annisa indra           | 30 | 30 | 25 | 72 | 57 |
| 1810522038 | Muhammad fakhri naufal | 20 | 20 | 10 | 75 | 57 |
+------------+------------------------+----+----+----+----+----+

这是我的 VueJS 视图代码:

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<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>
                            </tr>
                          </thead>
                          <tbody>
                            <template v-if="peserta.array != 0">
                            <tr v-for="(peserta, index) in penilaian1" :key="index">
                                <td>{{ peserta.nim }}</td>
                                <td>{{ peserta.nama }}</td>
                                <template v-if="peserta.array != penilaian1.array ">
                                    <td  v-for="sk in subkriteria" :key="sk.id_sk1">
                                      <i>Tidak ada data</i>
                                    </td>
                                </template>
                                <template v-else>   
                                    <td  v-for="penilaian in penilaian1" :key="penilaian.id_sk1">
                                        {{ penilaian.nilai }}
                                    </td>
                                </template>
                                <td>
                                <div class="btn-group">
                                  <router-link
                                  :to="{ name: 'penilaian1.show', params:{id: penilaian1.id}}"
                                  class="btn btn-sm btn-outline-info">Show</router-link>
                                </div>
                              </td>
                            </tr>
                            </template>
                          </tbody>
                        </table>

<script>
import axios from 'axios'


export default {
    
    computed:{
        countedMhs: function() {
            return this.peserta.filter(penilaian1 => penilaian1.nim==0);
        },          
    
        rolesByCategory() {
            return _.groupBy(this.penilaian1.nim ) 
        }  
        
    
    },

    data: function () {
        return {
            peserta: [],
            penilaian1: [],
            subkriteria: [],
            kriteria: [],
            loading: true,
        }
    },
    mounted() {
        this.loadData();
    },

    watch: {
        selected: {
            handler: function () {
                this.loadData();
            },
            deep: true
        }
    },

    methods: {
        loadData: function () {
            this.loading = true;

            Promise.all([
                this.loadPeserta(),
                this.loadPenilaian1(),
                this.loadTableSK1(),
                this.loadTableK1(),
                false
            ])
            .then(() => {
                [this.peserta, this.penilaian1, this.subkriteria, this.kriteria]
            })
            .catch(function (error) {
                console.log(error);
            });
        },
        loadPeserta: function () {
            axios.get('http://127.0.0.1:8000/api/penilaian1/peserta1', {
                    params: this.selected
                })
                .then((response) => {
                    this.peserta = response.data.data;
                })
                .catch(function (error) {
                    console.log(error);
                });
        },
        loadPenilaian1: function () {
            axios.get('http://127.0.0.1:8000/api/penilaian1', {
                    params: this.selected
                })
                .then((response) => {
                    this.penilaian1 = response.data.data;
                })
                .catch(function (error) {
                    console.log(error);
                });
        },
        loadTableSK1: function () {
            axios.get('http://127.0.0.1:8000/api/penilaian1/table_sk1', {
                params: this.selected
                })
                .then((response) => {
                    this.subkriteria = response.data.data;
                    this.loading = false;
                })
                .catch(function (error) {
                    console.log(error);
                });
        },
        loadTableK1: function () {
            axios.get('http://127.0.0.1:8000/api/penilaian1/table_k1', {
                    params: this.selected
                })
                .then((response) => {
                    this.kriteria = response.data.data;
                    this.loading = false;
                })
                .catch(function (error) {
                    console.log(error);
                });
        },
        
    }
}
</script>

但预期的结果是这样的:https://i.stack.imgur.com/SgaQo.png

图片显示所有10个nilai都被转置到列,但我只想基于NIM转置5个nilai(应该使用groupBy但我不知道如何计算)。

那么我如何使用 VueJS 将这些 JSON 数据从行转换到列?就像我的目标一样,提前致谢。

编辑: 我用 Composition API 和 Axios 尝试了 Nikola 的解决方案,但数据没有出现:

import axios from 'axios'
import { onMounted, ref, computed } from 'vue'
import SideBar from './../../../components/SideBar.vue'

export default {
    components: {
        SideBar,
    },

    setup() {
        let peserta1 = ref([])
        let result = ref([])
        let penilaian1 = ref([])
        let subkriteria = ref([])

        onMounted(() => {
            axios
                .get('http://127.0.0.1:8000/api/penilaian1')
                .then((result) => {
                    penilaian1.value = result.data
                })
                .catch((err) => {
                    console.log(err.response)
                })
        })

        onMounted(() => {
            axios
                .get('http://127.0.0.1:8000/api/penilaian1/table_sk1')
                .then((result) => {
                    subkriteria.value = result.data
                })
                .catch((err) => {
                    console.log(err.response)
                })
        })
        onMounted(() => {
            axios
                .get('http://127.0.0.1:8000/api/penilaian1/peserta1')
                .then((result) => {
                    peserta1.value = result.data
                })
                .catch((err) => {
                    console.log(err.response)
                })
        })
        const transpose = () => {
            penilaian1.value.forEach((dat) => {
                if (!result.value.find((r) => r.nim === dat.nim)) {
                    result.value.push({ nim: dat.nim, nama: dat.nama })
                }
            })
            penilaian1.value.forEach((dat) => {
                let res = result.value.find((r) => r.nim === dat.nim)
                res[dat.id_sk1] = dat.nilai
            })
            console.log(result)
        }

        return {
            peserta1,
            penilaian1,
            subkriteria,
            transpose,
        }
    },
}
<template>
    <div class="relative min-h-screen md:flex">
        <SideBar />
        <div class="flex-1">
            <div class="col-12">
                <h1 class="px-6 py-6 mb-6 text-3xl font-extrabold">
                    Data Pendaftar
                </h1>
            </div>
            <div class="col-12">
                <div class="flex-1">
                    <div class="overflow-y-auto sm:-mx-6 lg:-mx-8">
                        <div class="py-2 inline-clip sm:px-6 lg:px-12">
                            <div
                                class="overflow-hidden shadow-md sm:rounded-lg"
                            >
                                <table class="min-w-full">
                                    <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
                                                scope="col"
                                                class="relative px-6 py-3"
                                            >
                                                <span class="sr-only"
                                                    >Edit</span
                                                >
                                            </th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <!-- Product 1 -->

                                        <tr
                                            v-for="peserta1 in transpose"
                                            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"
                                            >
                                                {{ peserta1.nim }}
                                            </td>
                                            <td
                                                class="px-6 py-4 text-sm text-gray-500  whitespace-nowrap dark:text-gray-400"
                                            >
                                                {{ peserta1.nama }}
                                            </td>

                                            <td
                                                class="px-6 py-4 text-sm font-medium text-right  whitespace-nowrap"
                                            ></td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

更新 2,代码现在使用 watchEffect 工作:

watchEffect(() => {
            state.penilaian1.forEach((dat) => {
                if (!state.result.find((r) => r.nim === dat.nim)) {
                    state.result.push({ nim: dat.nim, nama: dat.nama })
                }
            })
            state.penilaian1.forEach((dat) => {
                let res = state.result.find((r) => r.nim === dat.nim)
                res[dat.id_sk1] = dat.nilai
            })
            console.log(state.result)
        })

结果如下: Overall result Detailed console.log result

现在我将弄清楚如何使用 v-for 调用成绩数据,但让我在下一个问题中回答

【问题讨论】:

    标签: javascript json axios vuejs3 vue-composition-api


    【解决方案1】:

    尝试如下:

    const data = [
      {"nim":1810112048,"nama":"Annisa indra","id_sk1":11,"nilai":30},
      {"nim":1810112048,"nama":"Annisa indra","id_sk1":12,"nilai":30},
      {"nim":1810112048,"nama":"Annisa indra","id_sk1":13,"nilai":25},
      {"nim":1810112048,"nama":"Annisa indra","id_sk1":21,"nilai":72},
      {"nim":1810112048,"nama":"Annisa indra","id_sk1":31,"nilai":57},
      {"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":11,"nilai":20},
      {"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":12,"nilai":20},
      {"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":13,"nilai":10},
      {"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":21,"nilai":75},
      {"nim":1810522038,"nama":"Muhammad fakhri naufal","id_sk1":31,"nilai":57}
    ]
    const result = [];
    data.forEach(dat => {
      if(!result.find(r => r.nim === dat.nim)) {
        result.push({"nim":dat.nim, "nama": dat.nama})
      }
    });
    data.forEach(dat => {
      let res = result.find(r => r.nim === dat.nim)
      res[dat.id_sk1] = dat.nilai
    });
    
    console.log(result)

    【讨论】:

    • 谢谢,但我如何调用/获取表格上的“结果”数据?
    • 我已经使用 Compostion API 和 Axios 尝试过这段代码,但是数据没有出现。有必要使用计算元素吗?
    • @NorthernOsprey 嘿伙计,你在哪里调用transpose 函数?
    • 我不是说调用transpose JavaScript 函数,它是你给的代码的方法名。
    • 好的,但是您在哪里/何时调用该方法?您需要在 monted 钩子中获取数据后调用它(顺便说一句,不要使用 3 个 onMounted 钩子,您可以将多个 api 调用合二为一)
    猜你喜欢
    • 2014-03-19
    • 2018-01-27
    • 1970-01-01
    • 2020-05-15
    • 2019-02-08
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    相关资源
    最近更新 更多