web-dev-qa-db-fra.com

Propriétés calculées dans les lignes Vuetify Datatable

J'utilise Vuetify et Vuetify/Datatables pour un site Web. Maintenant, je veux des propriétés computed sur chaque ligne de la table.

Pour ce faire, je devrais probablement faire un composant du <template> élément et ajouter des propriétés calculées à ce composant. J'ai essayé <template is="myComponent" :m="props.item"> mais cela n'a pas fonctionné.

<v-data-table
  :headers="headers"
  :items="items"
  hide-actions
  class="elevation-1"
>
  <template slot="items" slot-scope="props">
    <td>{{ THIS_VALUE_COMPUTED }}</td>
    <td class="text-xs-right">{{ props.item.calories }}</td>
    <td class="text-xs-right">{{ props.item.fat }}</td>
    <td class="text-xs-right">{{ props.item.carbs }}</td>
    <td class="text-xs-right">{{ props.item.protein }}</td>
    <td class="text-xs-right">{{ props.item.iron }}</td>
  </template>
</v-data-table>
7
Hendrik Jan

c'est une question un peu vieillotte mais ça pourrait marcher, ça vient de la documentation vuetify 2.0.19. Ici, vous pouvez faire une valeur calculée sur l'une des propriétés uniques de votre table.

<v-data-table
  :headers="headers"
  :items="items"
  hide-actions
  class="elevation-1"
>
   <template
            v-slot:item.calories="{ item }" >
    {{ THIS_VALUE_COMPUTED }}
  </template>
</v-data-table>
2
Alex

J'ai pu utiliser des propriétés calculées en incluant un composant supplémentaire (avec des propriétés calculées) et un élément supplémentaire <template>. Je ne suis pas vraiment content d'avoir deux éléments <template> L'un dans l'autre mais c'était le seul moyen de faire fonctionner cela. De meilleures solutions sont toujours les bienvenues.

( Exemple de codepen de travail )

JS (une modification de l'exemple Vuetify Datatable):

let myComponent = Vue.component('my-component', {
  props: {
    item: {
      type: Object,
      required: true,
    }
  },
  mounted: function() {
    console.log('mounted', this.item)
  },
  computed: {
    COMPUTED_PROPERTY: function() {
      return this.item.fat +
        this.item.carbs +
        this.item.protein
    }
  },
  template: `<tr>
    <td>{{ item.name }}</td>
    <td>{{ item.calories }}</td>
    <td>{{ COMPUTED_PROPERTY }}</td>
    <td>{{ item.iron }}</td>
  </tr>`
})

new Vue({
  el: '#app',
  mounted: function() {
    console.log('loaded')
  },
  components: { myComponent },
  data: () => ({
    pagination: {
      sortBy: 'name'
    },
    selected: [],
    headers: [
      {
        text: 'Dessert (100g serving)',
        align: 'left',
        value: 'name'
      },
      { text: 'Calories', value: 'calories' },
      { text: 'Fat + Carbs + Protein (g)', value: 'total' },
      { text: 'Iron (%)', value: 'iron' }
    ],
    items: [
      {
        value: false,
        name: 'Frozen Yogurt',
        calories: 159,
        fat: 6.0,
        carbs: 24,
        protein: 4.0,
        iron: '1%'
      },
      {
        value: false,
        name: 'Ice cream sandwich',
        calories: 237,
        fat: 9.0,
        carbs: 37,
        protein: 4.3,
        iron: '1%'
      },
      {
        value: false,
        name: 'Eclair',
        calories: 262,
        fat: 16.0,
        carbs: 23,
        protein: 6.0,
        iron: '7%'
      },
      {
        value: false,
        name: 'Cupcake',
        calories: 305,
        fat: 3.7,
        carbs: 67,
        protein: 4.3,
        iron: '8%'
      },
      {
        value: false,
        name: 'Gingerbread',
        calories: 356,
        fat: 16.0,
        carbs: 49,
        protein: 3.9,
        iron: '16%'
      },
      {
        value: false,
        name: 'Jelly bean',
        calories: 375,
        fat: 0.0,
        carbs: 94,
        protein: 0.0,
        iron: '0%'
      },
      {
        value: false,
        name: 'Lollipop',
        calories: 392,
        fat: 0.2,
        carbs: 98,
        protein: 0,
        iron: '2%'
      },
      {
        value: false,
        name: 'Honeycomb',
        calories: 408,
        fat: 3.2,
        carbs: 87,
        protein: 6.5,
        iron: '45%'
      },
      {
        value: false,
        name: 'Donut',
        calories: 452,
        fat: 25.0,
        carbs: 51,
        protein: 4.9,
        iron: '22%'
      },
      {
        value: false,
        name: 'KitKat',
        calories: 518,
        fat: 26.0,
        carbs: 65,
        protein: 7,
        iron: '6%'
      }
    ]
  }),

  methods: {
    changeSort (column) {
      if (this.pagination.sortBy === column) {
        this.pagination.descending = !this.pagination.descending
      } else {
        this.pagination.sortBy = column
        this.pagination.descending = false
      }
    }
  }
})

HTML:

<div id="app">
<v-app id="inspire">
  <v-data-table
    v-model="selected"
    :headers="headers"
    :items="items"
    select-all
    :pagination.sync="pagination"
    item-key="name"
    class="elevation-1"
  >
    <template slot="headers" slot-scope="props">
      <tr>
        <th
          v-for="header in props.headers"
          :key="header.text"
          :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
          @click="changeSort(header.value)"
        >
          <v-icon small>arrow_upward</v-icon>
          {{ header.text }}
        </th>
      </tr>
    </template>
    <template slot="items" slot-scope="props">
      <template :active="props.selected" @click="props.selected = !props.selected">
        <my-component :item="props.item">
        </my-component>
      </template>
    </template>
  </v-data-table>
</v-app>
</div>
1
Hendrik Jan