プログラミング

[NuxtJS]Vuetifyjsのv-data-tableのグループヘッダーをカスタマイズする

プログラミング
この記事は約12分で読めます。
スポンサーリンク

NuxtJSVuetify.jsv-data-tableのレコードをグループ化したときにグループヘッダーをカスタマイズする方法をメモしておきます。

スポンサーリンク

前提条件

  • vue:2.6.14
  • nuxt:2.15.8
  • vuetify:2.6.1

こちらから今回のソースコードを確認できます。

GitHub - koichi-ezato/nuxt-sample at v-data-tableグループヘッダーカスタマイズ
Contribute to koichi-ezato/nuxt-sample development by creating an account on GitHub.

グループ化

まずは、普通にv-data-tableのグループ化をしてみます。

DataTableCustom.vue

<template>
  <v-card>
    <v-card-title>データテーブルグループ化カスタマイズ</v-card-title>
    <v-data-table :items='items' :headers='headers' show-group-by group-by='group' />
  </v-card>
</template>

<script>
export default {
  name: 'DataTableCustom',
  data() {
    return {
      items: [
        { id: '1', name: '牛乳', value: 10, group: 'グループ1' },
        { id: '2', name: 'チーズ', value: 20, group: 'グループ2' },
        { id: '3', name: 'ヨーグルト', value: 30, group: 'グループ3' },
        { id: '4', name: 'バター', value: 40, group: 'グループ3' },
        { id: '5', name: '練乳', value: 50, group: 'グループ3' },
        { id: '6', name: 'クリーム', value: 60, group: 'グループ2' },
        { id: '7', name: 'アイスクリーム', value: 70, group: 'グループ2' },
        { id: '8', name: '脱脂粉乳', value: 80, group: 'グループ1' },
        { id: '9', name: '乳酸菌飲料', value: 90, group: 'グループ1' },
        { id: '10', name: 'ホエイプロテイン', value: 100, group: 'グループ1' },
      ],
      headers: [
        { text: 'ID', value: 'id', groupable: false },
        { text: '名称', value: 'name', groupable: false },
        { text: '値', value: 'value', groupable: false },
        { text: 'グループ', value: 'group' },
      ]
    }
  },
}
</script>

    <v-data-table :items='items' :headers='headers' show-group-by group-by='group' />

itemsにデータレコード、headersにテーブルヘッダーの情報を設定します。グループ化する場合は、show-group-bypropを指定します。group-byプロパティにグループ化するフィールド名を指定します。

グループヘッダーをカスタマイズする

グループヘッダーをカスタマイズするにはgroup.headerslotを使用します。

v-data-table API
API for the v-data-table component.
<template>
  <v-card>
    <v-card-title>データテーブルグループ化カスタマイズ</v-card-title>
    <v-data-table :items='items' :headers='headers' show-group-by group-by='group'>
      <template #[`group.header`]="{ group, items, headers, toggle, isOpen, remove }">
        <td>
          <v-btn @click="toggle" x-small icon :ref="group">
            <v-icon v-if="isOpen">mdi-minus</v-icon>
            <v-icon v-else>mdi-plus</v-icon>
          </v-btn>
          {{ group }}
          <v-btn @click='remove' x-small icon :ref='group'>
            <v-icon>mdi-close</v-icon>
          </v-btn>
        </td>
        <td>小計:{{ getTotal(items) }}</td>
        <td :colspan="headers.length-2"></td>
      </template>
    </v-data-table>
  </v-card>
</template>

<script>
export default {
  name: 'DataTableCustom',
  data() {
    return {
      items: [
        { id: '1', name: '牛乳', value: 10, group: 'グループ1' },
        { id: '2', name: 'チーズ', value: 20, group: 'グループ2' },
        { id: '3', name: 'ヨーグルト', value: 30, group: 'グループ3' },
        { id: '4', name: 'バター', value: 40, group: 'グループ3' },
        { id: '5', name: '練乳', value: 50, group: 'グループ3' },
        { id: '6', name: 'クリーム', value: 60, group: 'グループ2' },
        { id: '7', name: 'アイスクリーム', value: 70, group: 'グループ2' },
        { id: '8', name: '脱脂粉乳', value: 80, group: 'グループ1' },
        { id: '9', name: '乳酸菌飲料', value: 90, group: 'グループ1' },
        { id: '10', name: 'ホエイプロテイン', value: 100, group: 'グループ1' },
      ],
      headers: [
        { text: 'ID', value: 'id', groupable: false },
        { text: '名称', value: 'name', groupable: false },
        { text: '値', value: 'value', groupable: false },
        { text: 'グループ', value: 'group' },
      ]
    }
  },
  methods: {
    getTotal(items) {
      let total = 0
      total = items.reduce((prev, current) => {
        return prev + current.value
      }, 0)
      return total
    }
  }
}
</script>

今回はグループごとの値の小計を計算してグループヘッダーに表示しています。

グループの最後にサマリーレコードを追加することもできる

group.summaryslotを使用するとグループ化されたレコードの最後にサマリーレコードを表示することもできます。

<template>
  <v-card>
    <v-card-title>データテーブルグループ化カスタマイズ</v-card-title>
    <v-data-table :items='items' :headers='headers' show-group-by group-by='group'>
      <template #[`group.header`]="{ group, items, headers, toggle, isOpen, remove }">
        <td>
          <v-btn @click="toggle" x-small icon :ref="group">
            <v-icon v-if="isOpen">mdi-minus</v-icon>
            <v-icon v-else>mdi-plus</v-icon>
          </v-btn>
          {{ group }}
          <v-btn @click='remove' x-small icon :ref='group'>
            <v-icon>mdi-close</v-icon>
          </v-btn>
        </td>
        <td>小計:{{ getTotal(items) }}</td>
        <td :colspan="headers.length-2"></td>
      </template>
      <template #[`group.summary`]="{ items, headers }">
        <td>小計:{{ getTotal(items) }}</td>
        <td :colspan="headers.length-1"></td>
      </template>
    </v-data-table>
  </v-card>
</template>

<script>
export default {
  name: 'DataTableCustom',
  data() {
    return {
      items: [
        { id: '1', name: '牛乳', value: 10, group: 'グループ1' },
        { id: '2', name: 'チーズ', value: 20, group: 'グループ2' },
        { id: '3', name: 'ヨーグルト', value: 30, group: 'グループ3' },
        { id: '4', name: 'バター', value: 40, group: 'グループ3' },
        { id: '5', name: '練乳', value: 50, group: 'グループ3' },
        { id: '6', name: 'クリーム', value: 60, group: 'グループ2' },
        { id: '7', name: 'アイスクリーム', value: 70, group: 'グループ2' },
        { id: '8', name: '脱脂粉乳', value: 80, group: 'グループ1' },
        { id: '9', name: '乳酸菌飲料', value: 90, group: 'グループ1' },
        { id: '10', name: 'ホエイプロテイン', value: 100, group: 'グループ1' },
      ],
      headers: [
        { text: 'ID', value: 'id', groupable: false },
        { text: '名称', value: 'name', groupable: false },
        { text: '値', value: 'value', groupable: false },
        { text: 'グループ', value: 'group' },
      ]
    }
  },
  methods: {
    getTotal(items) {
      let total = 0
      total = items.reduce((prev, current) => {
        return prev + current.value
      }, 0)
      return total
    }
  }
}
</script>

最後に

レコードをグループ化した際に、グループの先頭に表示したいグループの情報、グループの末尾に表示したいグループの情報があるの思いますので、状況に応じて今回説明したslotsを活用していきたいですね。

こちらから今回のソースコードを確認できます。

GitHub - koichi-ezato/nuxt-sample at v-data-tableグループヘッダーカスタマイズ
Contribute to koichi-ezato/nuxt-sample development by creating an account on GitHub.
スポンサーリンク
スポンサーリンク
スポンサーリンク
KoEをフォローする
CodeLab

コメント

タイトルとURLをコピーしました