34
29

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.

Vue.jsで作る フォーム確認画面

Last updated at Posted at 2019-10-01

はじめに

アカウント登録などで、ユーザに情報を入力してもらったあとに、入力内容を確認してもらうための画面を用意しているサービスって多いですよね
SPAでそれを実現しようとすると、確認画面にデータを渡したりとか、戻ったときに入力内容が消えちゃったりして、頭を抱えました。
結果、こんな風に実装したよ〜、というのをご紹介できればと思います。

環境

Vue.js 2.6.10
vue-cli 3.9.1
vue-router 3.0.3

動作

動作確認用として、Githubにコード全文を上げています
https://github.com/tsk-wakabayashi/routing-nest-sample

Gifでみるとこんな感じ
Image from Gyazo

解説

基本的にはこちらの機能を使います
https://router.vuejs.org/ja/guide/essentials/nested-routes.html

簡単に説明すると、ネストされたルーティングの親に、パラメータを持たせます。

App.vueの中にメインのrouter-view

App.vue
<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

Index.vueの中にFormとConfirmをルーティングするrouter-viewを置いています。

Index.vue
<template>
  <div>
    <div>
      入力
      <span v-if="$route.meta.isConfirm">> 確認</span>
    </div>
    <router-view v-bind:user.sync="user"></router-view>
  </div>
</template>

Form.vueとConfirm.vueの親はIndex.vueとなり、親要素を介してデータのやり取りができます。

Form.vueとConfirm.vueを行き来しても、Index.vueはマウントされた状態のため、データが残り続けるという仕組みです。
これのいいところはブラウザバックをしてもデータが残るので、ユーザにも親切ですね

Form.vue
<template>
  <div>
    <form v-on:submit="$router.push('/confirm')">
      <div>
        名前
        <input v-model="user.name" type="text" required />
      </div>
      <div>
        パスワード
        <input v-model="user.password" type="password" required />
      </div>
      <button>確認する</button>
    </form>
  </div>
</template>

<script>
export default {
  props: {
    user: Object
  }
};
</script>
Confirm.vue
<template>
  <div>
    <div>名前: {{ user.name }}</div>
    <div>パスワード: {{ user.password }}</div>
    <button v-on:click="$router.back()">戻る</button>
  </div>
</template>

<script>
export default {
  props: {
    user: Object
  }
};
</script>

ルーティングは

  • '/'がフォームの入力画面
  • '/confirm'が確認画面です。

Indexのpathに引っかかったあとは、childrenの中にあるルーティングが優先されて判定されるイメージです。

router.js
export default new Router({
  mode: "history",
  routes: [
    {
      path: "/",
      component: Index,
      children: [
        {
          path: "/",
          component: Form
        },
        {
          path: "/confirm",
          component: Confirm,
          meta: {
            isConfirm: true
          }
        }
      ]
    }
  ]
});

今回のサンプルはIndex.vueから渡すデータをオブジェクトにしているので、”親が子のデータを勝手に変えてはいけない”というルールに反することが出来る書き方になっています。
ただ、入力項目が多いとその分データバインディングするのも大変ですし、ベストプラクティスになるものがあればご教示頂ければ幸いです。

さいごに

冒頭では確認画面を用意するサービスは多いと書きましたが、最近の傾向はどうなんでしょうか
モーダルで出すものもあれば、確認がないものもあるような気がします
それでもrouterをネストさせるのは、他にも使いみちがありそうですよね。

34
29
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
34
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?