LoginSignup
2
2

More than 1 year has passed since last update.

vuetifyのv-data-tableで入力テーブルを作る

Posted at

概要

vuetifyのv-data-tableで直接テーブルデータを編集したい場合の書き方を自分なりに解説していく。
基本的な構文などは既知とする。
リアクティブの探求とか行の挿入/削除とかはやらない。

環境

  • nuxt : 2.15.7
  • vue : 2.6.14
  • vuetify : 2.5.6

.vueファイルに一括でビューやデータを書いていく。

書く

とりあえずv-data-tableを使う

1行1列のデータを表示してみるソースの全体像はこんな感じ。
v-card使ってるのと、フッタを隠しているのは個人的な趣味。

<template>
  <v-app>
    <v-container>
      <v-row justify="start">
        <v-col cols="12">
          <v-card>
            <!-- とりあえず表示する -->
            <v-data-table
              :headers="headers"
              :items="items"
              hide-default-footer
            />
          </v-card>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</template>

<script>
export default {
  data() {
    return {
      headers: [{ text: "行1", value: "col1", align: "center" }],
      items: [{ col1: "hoge" }],
    }
  },
}
</script>

表示はこんな感じ。data()に書いたitemsがそのまま表示されているだけ。
firstOfAll.PNG

テキストボックスにする

各カラムにはslotを使用して入力用コンポーネントを指定できる。→参考
公式にも載っている。

書いていない部分は上記したものから変わっていない。
(solo, flat, hide-details は趣味)

<v-data-table :headers="headers" :items="items" hide-default-footer>
  <!-- テキストボックス -->
  <template #[`item.col1`]="{ item }">
    <v-text-field 
      v-model="item.col1"
      solo
      flat
      hide-details 
    />
  </template>
</v-data-table>

これでデータが入力できるようになった。
textField.PNG

ただし注意として、ソートを有効にしてデータを入力すると、即座に順番が入れ替わってしまうので入力中はソートを切るなどの工夫が必要。v-model.lazyなども試したがうまくいかなかった。

チェックボックスを追加する

テキスト入力だけでなく、チェックボックスとかラジオボタンとか普通のボタンとかも指定できる。
styleはチェックボックス付近のみクリック可能に、classは位置をいい感じにしたいので。indigoは趣味。
...はソースコードを省略していることを表している(特別な記述とかではない)。

...
  <v-data-table :headers="headers" :items="items" hide-default-footer>
    <!-- テキストボックス(縦に長くなるので1行にまとめた) -->
    <template #[`item.col1`]="{ item }">
      <v-text-field v-model="item.col1" solo flat hide-details />
    </template>
    <!-- チェックボックス -->
    <template #[`item.col2`]="{ item }">
      <v-checkbox
        v-model="item.col2"
        hide-details
        color="indigo"
        style="width: 25px" 
        class="pa-0 ma-0 ml-5"
      />
    </template>
  </v-data-table>

...
<script>
...

  data() {
    return {
      headers: [
        { text: "行1", value: "col1", align: "center" },
        { text: "行2", value: "col2", align: "center" }, // チェックボックス用
      ],
      items: [{ col1: "hoge", col2: true }],
    }
  },

...

checkbox.PNG

ラジオボタンを追加する

行の中で複数の選択肢から1つを選ばせる場合はラジオボタンを使用することもできる。
セレクトボックスと見た目が違うだけなので、相当こだわりがない場合はセレクトボックスのほうが楽。
複数レコードのなかから1つ選ぶラジオボタンの場合は別途処理を記述する必要があるかも?

v-layoutは1行で表示するため(このディレクティブを外せば縦に表示される)。
classは位置調整と、ラジオボタンが近づきすぎるのを防ぐため。

...
  <!-- ラジオボタン -->
  <template #[`item.col3`]="{ item }">
    <v-radio-group v-model="item.col3"> <!-- 各行でラジオボタンをグループ化 -->
      <v-layout row justify-center> <!-- ラジオボタンを横1行で表示する -->
        <v-radio
          v-for="r in radios"
          :key="r.id"
          :label="r.label"
          :value="r.id"
          class="my-0 mr-4"
        />
      </v-layout>
    </v-radio-group>
  </template>

...
<script>
...

  data() {
    return {
      headers: [
        { text: "行1", value: "col1", align: "center" },
        { text: "行2", value: "col2", align: "center" },
        { text: "行3", value: "col3", align: "center" },
      ],
      items: [{ col1: "hoge", col2: true, col3: 1 }],
      // ラジオボタンアイテム
      radios: [
        { id: 1, label: "foo" },
        { id: 2, label: "bar" },
      ],
    }
  },
...

radio.PNG

セレクトボックスを追加する

ラジオボタンと使用感は似ているが、セレクトボックスも使用可能。
ラジオボタンよりコードが簡潔になる。

...
  <!-- セレクトボックス -->
  <template #[`item.col4`]="{ item }">
    <v-select v-model="item.col4" :items="selects" solo flat hide-details />
  </template>

...
<script>
...

  data() {
    return {
     headers: [
       { text: "行1", value: "col1", align: "center" },
       { text: "行2", value: "col2", align: "center" },
       { text: "行3", value: "col3", align: "center" },
       { text: "行4", value: "col4", align: "center" },
     ],
...
    // セレクトボックスアイテム
    selects: [
      { text: "ace", value: 1 },
      { text: "bob", value: 2 },
    ],
  },
...

selects.PNG

グリッドテーブル使ったらいいんじゃないの?

めぼしいのは以下くらいだった。

ただし、書き方にクセがあったり制約があったりするので、意外とvuetifyが楽だったりする。

ちなみに、cheetah gridは<canvas>がうまく表示されずに挫折。
vue-tabulatorはチェックボックスの挙動がいまいちだったので挫折した。

2
2
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
2
2