はじめに
アカウント登録などで、ユーザに情報を入力してもらったあとに、入力内容を確認してもらうための画面を用意しているサービスって多いですよね
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
解説
基本的にはこちらの機能を使います
https://router.vuejs.org/ja/guide/essentials/nested-routes.html
簡単に説明すると、ネストされたルーティングの親に、パラメータを持たせます。
App.vueの中にメインのrouter-view
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
Index.vueの中にFormとConfirmをルーティングするrouter-viewを置いています。
<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はマウントされた状態のため、データが残り続けるという仕組みです。
これのいいところはブラウザバックをしてもデータが残るので、ユーザにも親切ですね
<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>
<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の中にあるルーティングが優先されて判定されるイメージです。
export default new Router({
mode: "history",
routes: [
{
path: "/",
component: Index,
children: [
{
path: "/",
component: Form
},
{
path: "/confirm",
component: Confirm,
meta: {
isConfirm: true
}
}
]
}
]
});
今回のサンプルはIndex.vueから渡すデータをオブジェクトにしているので、”親が子のデータを勝手に変えてはいけない”というルールに反することが出来る書き方になっています。
ただ、入力項目が多いとその分データバインディングするのも大変ですし、ベストプラクティスになるものがあればご教示頂ければ幸いです。
さいごに
冒頭では確認画面を用意するサービスは多いと書きましたが、最近の傾向はどうなんでしょうか
モーダルで出すものもあれば、確認がないものもあるような気がします
それでもrouterをネストさせるのは、他にも使いみちがありそうですよね。