3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vuetifyのv-data-tableに行クリックで行展開する方法

Last updated at Posted at 2021-11-12

はじめに

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>

test.png

行クリックによる行展開の実装方法

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>

Videotogif.gif

これで行クリックによる行展開ができるようになりました。
「!slot.isExpanded」 で行展開しているかどうかをbooleanで判別し、展開されてないなら「true」を返します。
「slot.expand(!slot.isExpanded)」で上記のようにtrueなら行展開されるようなロジックです。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?