Help us understand the problem. What is going on with this article?

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

はじめに

アカウント登録などで、ユーザに情報を入力してもらったあとに、入力内容を確認してもらうための画面を用意しているサービスって多いですよね
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をネストさせるのは、他にも使いみちがありそうですよね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした