kz’s blog

興味のあることについて書いていきます。

Vue UI を使ってユーザ管理機能を作る②

www.kz62.net

前回の記事ではユーザ管理機能の一覧表示まで作成しました。今回はその続きをやっていきます。

ユーザ編集の作成

ユーザ編集画面は、ユーザ管理画面の新規登録および一覧にて編集を選択した際に画面遷移するようにします。

パスの追加

  • src/router.js にパスを追加します。この時、ユーザIDをパスに含めることで編集するユーザを判断できるようにします。
    {
      path: '/user/:id',
      name: 'user-edit',
      component: () => import('./views/UserEdit.vue')
    }

これを動的ルートマッチングと言います。

www.kz62.net

ユーザ編集の vue を作成する

  • パスを追加した段階で画面を確認しに行くとエラーが起きているので vue を作成します。

  • src/views/UserEdit.vue を作成する。(UserList.vue をコピーしてしまいましょう。)

src/views/UserEdit.vue

<template>
  <div>
    <h1>ユーザ編集</h1>
  </div>
</template>

<script>
export default {
  data () {
    return {
    }
  }
}
</script>
  • これでとりあえずエラーはなくなります。

入り口を作る

  • 上で追加した画面に飛べるように入り口を作ります。一覧から編集ボタンを押した際に画面遷移するようにします。
src/views/UserList.vue

<template>
  <div>
    <h1>ユーザ管理</h1>
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>名前</th>
          <th>登録日時</th>
          <th>更新日時</th>
          <th>編集</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(user, index) in users" :key="index">
          <td>{{ user.id }}</td>
          <td>{{ user.name }}</td>
          <td>{{ user.created_at }}</td>
          <td>{{ user.updated_at }}</td>
          <td>
            <router-link :to="{ name: 'user-edit', params: { id: user.id } }"><button>編集</button></router-link>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
  • 編集列と編集ボタンを追加しています。

  • これで編集ボタンを押すと編集画面に遷移できるようになります。 また、選択する ID によって URL が変化することも確認できるかと思います。

ID で指定したユーザを表示する

  • まず、ユーザ配列から引数で指定した ID のユーザを取得する機能を作成します。
src/store.js

  getters: {
    // ID で指定したユーザを取得
    getUser: state => id => {
      // 対象の ID をディープコピーして返す
      return Object.assign({}, state.users.filter(user => user.id == id)[0])
    }
  }
  • getters は state と同じ階層に配置して下さい。

  • ディープコピーしている理由は、テキストフィールド等で編集した後、画面上部のリンクで戻った場合でも変更が反映されてしまうためです。

  • 次に編集画面のスクリプトで上記を呼び出して指定したユーザを参照できるようにします。

src/views/UserEdit.vue

// 修正前
  data () {
    return {
    }
  }

// 修正後
  data () {
    return {
      user: this.$store.getters.getUser(this.$route.params.id)
    }
  }
  • 続いて、テンプレート側で参照します。
src/views/UserEdit.vue

// 修正前
    <h1>ユーザ編集</h1>

// 修正後
    <h1>ユーザ編集</h1>
    ユーザID: {{ user.id }}
    <input v-model="user.name">
  • これで一覧で選択したユーザが編集画面に表示されるようになりました。

完了ボタンの設置

  • 変更を反映する時、Vuex の機能を使用しているので、必ず store を介して反映させるようにします。

  • src/store.js に空の mutations があるかと思います。そこにユーザ更新を作成します。

(公式ドキュメント ミューテーション | Vuex ではストアの更新は mutasions をコミットすることが唯一の方法と書いてありますが、直接更新することができてしまう気がします。詳しい方いらっしゃいましたら教えていただけるとありがたいです。)

src/store.js

  mutations: {
    // ユーザ更新
    updUser (state, user) {
      state.users.forEach(o => {
        if (o.id == user.id) {
          o.name = user.name
          o.updated_at = new Date()
        }
      })
    }
  },
  • 次に編集画面から上で作成したストアのユーザ更新を呼べるようにスクリプトに以下を追加します。
src/views/UserEdit.vue

  methods: {
    complete () {
      this.$store.commit('updUser', this.user)
    }
  }
  • methods は data () と同じ階層に配置して下さい。

  • ストアの mutations は commit で呼び出すことになります。第一引数にファンクション名を渡します。

  • 最後にテンプレートに完了ボタンを置きます。

src/views/UserEdit.vue

    <router-link to="../user"><button @click="complete()">完了</button></router-link>

編集機能の確認

以上で編集ボタンを押すことで、テキストで変更した内容が一覧に反映されていると思います。

今回は以上になります。次回、新規登録機能を作りたいと思います。

www.kz62.net