はじめに
Vuetifyでデータテーブルを実装することがあり、行クリックで行展開したいなと思ってました。
そこで実装してみた内容をメモしておこうと思います。
行展開の実装方法
行展開ではshow-expandを指定すると、行展開アイコンが表示されて展開できるようになります。
<template>
<v-data-table :headers="headers" :items="items" show-expand>
<template v-slot:expanded-item="{ headers, item }">
<td :colspan="headers.length">
<div style="padding: 5px">
<h4>趣味</h4>
<ul>
<li v-for="hobby of item.hobbies" :key="hobby">
{{ hobby }}
</li>
</ul>
</div>
</td>
</template>
</v-data-table>
</template>
<script>
export default {
data() {
return {
headers: [
{ text: "ID", value: "id" },
{ text: "氏名", value: "name" },
{ text: "誕生日", value: "birthday" },
{ text: "年齢", value: "age" },
],
items: [
{
id: 1,
name: "山田太郎",
birthday: "1990/1/1",
age: 31,
hobbies: ["サッカー", "野球"],
},
{
id: 2,
name: "佐藤花子",
birthday: "1991/1/1",
age: 30,
hobbies: ["茶道", "テニス", "スキー"],
},
{
id: 3,
name: "田中一郎",
birthday: "1992/1/1",
age: 29,
hobbies: ["ピアノ", "柔道", "ダンス", "ボルダリング"],
},
],
};
},
};
</script>
行クリックによる行展開の実装方法
v-data-table APIのイベントを確認してみると、「click:row」というものがあります。
引数を2つ渡すことができ、1つ目の引数は「クリックされた行データ(item)」、2つ目の引数は「itemスロットによる関連データ」を取ることができるみたいです。
以下はitemスロットのデータみたいなのですが、「expand」と「isExpanded」を利用することで行クリックの開閉ができそうです。
any, {
expand: (value: boolean) => void,
headers: DataTableHeader[],
isExpanded: boolean,
isMobile: boolean,
isSelected: boolean,
item: any,
select: (value: boolean) => void
}
Emits when a table row is clicked. This event provides 2 arguments: the first is the item data that was clicked and the second is the other related data provided by the item slot. NOTE: will not emit when table rows are defined through a slot such as item or body.
<template>
<v-data-table
:headers="headers"
:items="items"
show-expand
@click:row="(item, slot) => slot.expand(!slot.isExpanded)"
>
<template v-slot:expanded-item="{ headers, item }">
<td :colspan="headers.length">
<div style="padding: 5px">
<h4>趣味</h4>
<ul>
<li v-for="hobby of item.hobbies" :key="hobby">
{{ hobby }}
</li>
</ul>
</div>
</td>
</template>
</v-data-table>
</template>
<script>
export default {
data() {
return {
headers: [
{ text: "ID", value: "id" },
{ text: "氏名", value: "name" },
{ text: "誕生日", value: "birthday" },
{ text: "年齢", value: "age" },
],
items: [
{
id: 1,
name: "山田太郎",
birthday: "1990/1/1",
age: 31,
hobbies: ["サッカー", "野球"],
},
{
id: 2,
name: "佐藤花子",
birthday: "1991/1/1",
age: 30,
hobbies: ["茶道", "テニス", "スキー"],
},
{
id: 3,
name: "田中一郎",
birthday: "1992/1/1",
age: 29,
hobbies: ["ピアノ", "柔道", "ダンス", "ボルダリング"],
},
],
};
},
};
</script>
これで行クリックによる行展開ができるようになりました。
「!slot.isExpanded」 で行展開しているかどうかをbooleanで判別し、展開されてないなら「true」を返します。
「slot.expand(!slot.isExpanded)」で上記のようにtrueなら行展開されるようなロジックです。