Vue.js + Vuetify using v-data-table within v-for

gvon79 picture gvon79 · Aug 12, 2017 · Viewed 9.2k times · Source

I have 2 computed arrays, homeTeam and awayTeam. The code below does work to generate 2 tables to display the homeTeam and awayTeam, how can I simplify the code to only create the table once and loop through the homeTeam and awayTeam. I tried wrapping it in a v-for with an array of ['homeTeam','awayTeam], but that did not work. The computed works, everything below works, I just want to simplify the template.

<v-flex xs12 md6>
    <v-data-table :headers="headers" :items="homeTeam" hide-actions class="elevation-1 white">
        <template slot="items" scope="props">
            <td class="text-xs-right" v-model="gamesheet.number">{{ props.item.number }}</td>
            <td v-model="gamesheet.name">{{ props.item.name }}</td>
        </template>
    </v-data-table>
</v-flex>

<v-flex xs12 md6>
    <v-data-table :headers="headers" :items="awayTeam" hide-actions class="elevation-1 white">
        <template slot="items" scope="props">
            <td class="text-xs-right" v-model="gamesheet.number">{{ props.item.number }}</td>
            <td v-model="gamesheet.name">{{ props.item.name }}</td>
        </template>
    </v-data-table>
</v-flex>

_

computed: {
    homeTeam() {
        return this.players.filter((player) => {
            return player.team ==  this.gameinfo.home;
        })
    },
    awayTeam() {
        return this.players.filter((player) => {
            return player.team == this.gameinfo.away;
        })
    },
    spares() {
        return this.players.filter((player) => {
            return player.team !=  this.gameinfo.home && player.team != this.gameinfo.away;
        })
    },
},

here's my attempt with a v-for, I understand why this would not work.

    <template v-for="roster in rosters">
            <v-flex xs12 md6>
                <v-data-table :headers="headers" :items="roster" hide-actions class="elevation-1 white">
                    <template slot="items" scope="props">
                        <td class="text-xs-right" v-model="gamesheet.number">{{ props.item.number }}</td>
                        <td v-model="gamesheet.name">{{ props.item.name }}</td>
                        <td class="text-xs-right" v-model="gamesheet.position">{{ props.item.position }}</td>
                        <td class="text-xs-right" v-model="gamesheet.goal">{{ props.item.goal }}</td>
                        <td class="text-xs-right" v-model="gamesheet.assist">{{ props.item.assist }}</td>
                        <td class="text-xs-right" v-model="gamesheet.team">{{ props.item.team }}</td>
                    </template>
                </v-data-table>
            </v-flex>
        </template>

... and in the script...

    data () {
        return {
            rosters: ['homeTeam', 'awayTeam'],
        }
    },
    computed: {
        homeTeam() {
            return this.players.filter((player) => {
                return player.team ==  this.gameinfo.home;
            })
        },
        awayTeam() {
            return this.players.filter((player) => {
                return player.team == this.gameinfo.away;
            })
        },

Answer

Bert picture Bert · Aug 12, 2017

I think you could use v-for in this way:

<template v-for="team in [homeTeam, awayTeam]">
  <v-flex xs12 md6>
    <v-data-table :headers="headers" :items="team" hide-actions class="elevation-1 white">
      <template slot="items" scope="props">
          <td class="text-xs-right" v-model="gamesheet.number">{{ props.item.number }}</td>
          <td v-model="gamesheet.name">{{ props.item.name }}</td>
      </template>
    </v-data-table>
  </v-flex>
</template>

There were a couple problems with your initial try. First computed values are not available to be used in the data function (they are initialized later). Second, you quoted the values, which means that rosters is just an array of two strings.

Another approach you could take would be to make rosters a computed value.

computed:{
  rosters(){
    return [this.homeTeam, this.awayTeam]
  }
}