• 技術が集うTECH GUILD

    ユーザ管理画面のUIをVeutifyのData tableを使って作ってみました。

    ほとんどは公式のリファレンスを参考にしました。

    https://vuetifyjs.com/ja/components/data-tables

    概要

    • ここまでの経緯
    • Data tableで作ったものの紹介
    • ハマったところ
    • 今後の課題

    詳細

    ここまでの経緯

    以前の記事で、RailsでWebAPIを作り、ユーザ情報を管理するテーブルを作成しました。
    このフロント部分にあたるものを、Vueで作成しており、今回VuetifyのData tableというコンポートネントを利用して作ってみたので、紹介します。

     

    ソースはこちらに挙げました。

    Data table で作ったものの紹介

    GIFアニメーションで紹介

    まずは以下のGIFアニメをご覧ください。
    新規作成から更新、削除、フィルタの操作をしています。
    入力フォームのバリデーションや、リストのページネーションも効いています。
    撮影時に忘れましたが、カラムヘッダをクリックすることで、ソートも可能です。

    Data tableのサンプルの一番下に、CURDアクション付きのサンプルがあります。
    今回はこれをベースにしました。

    一覧表示

    DBのユーザを一覧表示します。Axiosで取ってきた一覧をData tableのitemsに設定しています。

    ユーザ一覧の取得処理

        // ユーザ一覧
        indexUsers () {
          this.userList = [];
          axios.get("http://localhost:3000/users")
          .then( response => {
            this.userList = response.data;
            console.log("Index : record num=" + this.userList.length);
          })
          .catch( error => {
            console.log("Error : " + response);
          });
        },

    <v-data-table>で様々なオプションを設定します。

          <v-data-table
             :headers="headers"
             :items="userList"
             :search="search"
             rows-per-page-text=""
             :rows-per-page-items="[]"
             class="elevation-1"
             v-show="!deleteDialog"
          >

    :headersでヘッダを定義しています。ヘッダの定義はdata()です。

          headers: [
             { text: 'ID', align: 'center', value: 'id' },
             { text: '名前', align: 'center', value: 'name' },
             { text: '年齢', align: 'center', value: 'age' },
             { text: 'メールアドレス', align: 'center', value: 'mail' },
             { text: '操作', align: 'center', value: 'action', sortable: false }
          ],

    テーブルボディ部の描画は

            <template slot="items" slot-scope="props">
              <td class="text-xs-center">{{ props.item.id }}</td>
              <td class="text-xs-center">{{ props.item.name }}</td>
              <td class="text-xs-center">{{ props.item.age }}</td>
              <td class="text-xs-center">{{ props.item.mail }}</td>
              <td class="justify-center layout px-0">
                <!-- 編集ボタン -->
                <v-icon class="mr-2" @click="editUser(props.item.id)">
                  edit
                </v-icon>
                <!-- 削除ボタン -->
                <v-icon @click="openDeleteDialog(props.item.id)">
                  delete
                </v-icon>
              </td>
            </template>

    編集ボタンと削除ボタンを入れています。

    それぞれidを渡すことで処理します。

    :searchがフィルター用のキーワード覧を表示します。

    rows-per-page-text=””と:rows-per-page-items=”[]”は、標準では、下部に1ページあたりの件数のプルダウンとそれを示す文字列が表示されますが、不要であるため(1ページ5件固定に設定)、非表示にする指定です。

    v-show=”!deleteDialog”は、削除確認ダイアログを出した際に、テーブルを非表示にします。これは、ダイアログを表示した際、ダイアログが透過されてしまい、背景のテーブルボディが透けて見えてしまったためです。やむをえず、削除確認ダイアログが表示されている間、テーブルボディを非表示とする応急処置をしました。
    適切な対応はダイアログに背景色を設定することと推測しますが、うまく設定できませんでした。
    新規や更新時の入力フォームは問題なく、原因はわかっていません。

    ページネーションは自動で入っており、右下の次ページボタンを押すと、次のページに遷移します。

    新規作成

    右上の+ボタンを押します。

            <v-btn fab dark small color="dark" class="mb-2"
              @click="dialog=true"
            >
              <v-icon dark>add</v-icon>
            </v-btn>

    <v-icon>add</v-icon>でアイコンを利用できました。<v-btn>にfab属性を入れると丸になります。

    バリデーションは以下の項目それぞれに設定しました。

    • ユーザ名
      必須、16文字以下
    • 年齢
      数値のみ
    • メールアドレス
      @マーク前後に文字を含む

    <v-text-field>内にrulesを書きました。

                        <v-text-field
                          v-model="selectedUser.name"
                          label="ユーザ名(*)"
                          :rules="nameRules"
                          :counter="16"
                          required
                        ></v-text-field>
                      </v-flex>
                      <v-flex xs12 sm6>
                        <v-text-field
                          v-model="selectedUser.age"
                          label="年齢"
                          :rules="ageRules"
                        ></v-text-field>
                      </v-flex>
                      <v-flex xs12>
                        <v-text-field
                          v-model="selectedUser.mail"
                          label="メールアドレス(*)"
                          :rules="mailRules"
                          required
                        ></v-text-field>
          nameRules: [
            v => !!v || 'ユーザ名は必須です',
            v => v.length <= 16 || 'ユーザ名は16文字までです'
          ],
    
          ageRules: [
            v => /^[0-9]*$/.test(v) || '年齢は数値で入力してください'
          ],
    
          mailRules: [
            v => !!v || 'メールアドレスは必須です',
            v => /.+@.+/.test(v) || '無効なメールアドレスです'
          ]

    編集/削除

    編集したいレコードのペンのアイコンをクリックすることで、編集が可能です。

    また、ゴミ箱アイコンで削除が可能です。

    フィルタ

    右上のSearchと書かれた入力ボックスでフィルタをかけられます。

    ここはリアルタイムに反映されます。検索対象カラムは全てです。

    ソート

    ヘッダーカラムをクリックすると照準降順でソートできます。

    下の画像は年齢でソートしたところ。

    ハマったところ

    • フッター部分の1ページあたりの件数を変更するプルダウン、及びそのテキストの変更方法がリファレンスに載っておらず、探しました。GitHub上のやりとりで、rows-per-page-textとrows-per-page-itemsを設定することがわかりました。

    今後の課題

    • バリデート処理で、Vee Validateを使用してみる
    • バリデート処理で、警告メッセージを赤くする
    • 削除確認ダイアログでダイアログが透過しないようにする(現状のテーブルボディの非表示をなくす)

    参考

    https://vuetifyjs.com/ja/components/data-tables#example-crud

     


    コメントを残す

    このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください