NuxtJS
の Vuetify
の v-data-table
のレコードをグループ化したときにグループヘッダーをカスタマイズする方法をメモしておきます。
前提条件
- vue : 2.6.14
- nuxt : 2.15.8
- vuetify : 2.6.1
こちらから今回のソースコードを確認できます。
グループ化
まずは、普通に v-data-table
のグループ化をしてみます。
DataTableCustom.vue
template
タグ部分
<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' },
]
}
},
}
<v-data-table :items='items' :headers='headers' show-group-by group-by='group' />
items
にデータレコード、 headers
にテーブルヘッダーの情報を設定します。グループ化する場合は、 show-group-by
prop を指定します。 group-by
プロパティにグループ化するフィールド名を指定します。
グループヘッダーをカスタマイズする
グループヘッダーをカスタマイズするには group.header
slot を使用します。
template
タグ部分
<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
}
}
}
今回はグループごとの値の小計を計算してグループヘッダーに表示しています。
グループの最後にサマリーレコードを追加することもできる
group.summary
slot を使用するとグループ化されたレコードの最後にサマリーレコードを表示することもできます。
template
タグ部分
<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
}
}
}
最後に
レコードをグループ化した際に、グループの先頭に表示したいグループの情報、グループの末尾に表示したいグループの情報があるの思いますので、状況に応じて今回説明した slots
を活用していきたいですね。
こちらから今回のソースコードを確認できます。
コメント