Home > Net >  Pass extra data on the first iteration of a v-for loop
Pass extra data on the first iteration of a v-for loop

Time:03-15

I'm creating a table with a json object given by an API The API data looks like this:

const data = {
    period1: [
        { uur: '1', klas: '4c, 4d', lokaal: '---', absent: 'Nele', tekst: 'les LO gaat door', vervanger: '---' },
        { uur: '1', klas: '2b', lokaal: 'D 3.01', absent: 'Jan', tekst: 'thuis na mail', vervanger: 'Robbe' }
    ],
    period2: [
        { uur: '2', klas: '4c, 4d', lokaal: '---', absent: 'Nele', tekst: 'les LO gaat door', vervanger: '---' }
    ],
    lunch: []
};

My table view has a bunch of <tbody>'s eg:

<template>
  <table cellpadding="0" cellspacing="0" border="0">
    <tbody>
      <TableRow /> <!-- row component -->
    </tbody>
    <tbody>
    ...

  </table>

The first iteration should have an extra <td> with the given period (prop) and in the <slot> an html element should be passed. For example, data.lunch needs <img src="/assets/images/bread.svg">

I was able to use v-for to create the other table rows, but i can't figure out the first one:

<TableRow v-for="item in witteLessen.period1" :key="item" :absent="item.absent" :classroom="item.lokaal" :grade="item.klas" :message="item.tekst" :substitute="item.vervanger" />

(i planned on passing item as a prop to make it cleaner, but i want it to work first.

TableRow's <template> looks like this:

<template>
    <tr>
        <td :rowspan="rowspan"  width="5%" v-if="hourLabel"><slot></slot></td>
        <td width="20%">{{ absent }}</td>
        <td width="7%">{{ grade }}</td>
        <td width="20%">{{ substitute }}</td>
        <td width="7%">{{ classroom }}</td>
        <td>{{ message }}</td>
    </tr>
</template>

I also made a pen of the code i'm trying to port over to vue that might help with clarifying: https://codepen.io/maxtechnics/pen/eYymXOM

CodePudding user response:

You should use index with the loop and then conditionally render HTML the first item with index.

I made this sandbox for you to try this approach: https://codesandbox.io/s/objective-hertz-kswvyd?file=/src/components/Table.vue

Edit: added most important bits from the codesandbox

The table:

<template>
    <table cellpadding="0" cellspacing="0" border="0">
        <tbody>
            <TableRow
                v-for="(item, index) of items.period1"
                :key="index"
                :absent="item.absent"
                :classroom="item.lokaal"
                :grade="item.klas"
                :message="item.tekst"
                :substitute="item.vervanger">
                <td v-if="index === 0">HTML THAT YOU WANT GOES HERE</td>
            </TableRow>
        </tbody>
    </table>
</template>

TableRow

<template>
    <tr>
        <slot></slot>
        <td width="20%">{{ absent }}</td>
        <td width="7%">{{ grade }}</td>
        <td width="20%">{{ substitute }}</td>
        <td width="7%">{{ classroom }}</td>
        <td>{{ message }}</td>
    </tr>
</template>

  • Related