Search code examples
vuejs3

Vue3 composition api transform props multidimensional Array into list


I'm using vue3 with composition api and I receive a props from db as a multidimensional array on page loading like this:

[
   {name: 'Jack', seat: '12', id: 1, ...},
   {name: 'Jack', seat: '13', id: 2, ...},
   {name: 'Luis', seat: '21', id: 3, ...},
   {name: 'Manuel', seat: '4', id: 4, ...},
   {name: 'Jack', seat: '14', id: 5, ...},
   ...
]

I'm already using it to have a view in the page as a standard list one by one but I need to create another table, after the previous, with names and the list of your seats (in case more than one).

Example:

Jack: 12,13,14
Luis: 21
Manuel: 4,5,6
....

I tried to use a template but I have some problems to achive this result, I tried using table and div tags but the output is wrong with break line in the middle or skipping the row. I don't know if there is a way to achive it without change the props structure (to have no problems on the previous table)

do you have any ideas? Thanks in advance Roberto


Solution

  • Use computed and transform your data into needed format inside it:

    Playground

    <script setup>
    import { onMounted, reactive, computed} from 'vue'
    const data = reactive([]);
    
    onMounted(async() => {
       const fetchedData = await [
       {name: 'Jack', seat: '12', id: 1},
       {name: 'Jack', seat: '13', id: 2},
       {name: 'Luis', seat: '21', id: 3},
       {name: 'Manuel', seat: '4', id: 4},
       {name: 'Jack', seat: '14', id: 5},
       ];
    
       data.push(...fetchedData);
    });
    const seats = computed(() => 
      data.reduce((r, {name, seat}) => ((r[name] ??= []).push(seat),r), {}));
    </script>
    
    <template>
      <div v-for="(nums, name) in seats" :key="name">
        {{ name }} : {{ nums.join(', ') }}
      </div>
    </template>