はじめに
こんにちは。
Kojirockの1人アドベントカレンダー Advent Calendar 2018の4日目の記事です。
以下の本を読んで勉強できたことを記載していきます。
今回は第4章です。
- 作者: 川口和也,喜多啓介,野田陽平,手島拓也,片山真也
- 出版社/メーカー: 技術評論社
- 発売日: 2018/09/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
4章 Vue Routerを活用したアプリケーション開発
目次
4.1 Vue Routerによるシングルページアプリケーション
4.2 ルーティングの基礎
4.3 実践的なルーティングのための機能
4.4 サンプルアプリケーションの実装
4.5 Vue Routerの高度な機能
4.1 Vue Routerによるシングルページアプリケーション
こちらでは、Vue Routerの概要を紹介してくれています。
簡単な使い方としては、以下のような定義です。
new VueRouter({ routes: [ { path: '/profile', component: Profile }, { path: '/about', component: About } ] })
該当するpathに応じて指定したコンポーネントを表示するという具合のようです。
その他の便利な機能があるので、この後出てくることを期待しておきます。
ちなみに、自分はSPAのwebアプリケーション開発は経験あるのですが、残念ながらバックエンド側だったので、フロントエンド側はノータッチでした。
この辺は興味津々です。
4.2 ルーティングの基礎
こちらでは、前述したRouterの簡単な定義を使用して、実際に動くものの紹介がありました。
<!DOCTYPE html> <html> <head> <title>Page Title</title> <script src="https://unpkg.com/vue@2.5.17"></script> <script src="https://unpkg.com/vue-router@3.0.1"></script> </head> <body> <div id="app"> <router-link to="/">トップページ</router-link> <router-link to="/news">ニュース</router-link> <router-link to="/profile">プロフィール</router-link> <router-view></router-view> </div> <script> const router = new VueRouter({ routes: [ { path: '/', component: { template: '<div style="background:red;">トップページ</div>' } }, { path: '/news', component: { template: '<div style="background:green;">ニュースページ</div>' } }, { path: '/profile', component: { template: '<div style="background:yellow;">プロフィールページ</div>' } } ] }) new Vue({ el: '#app', router: router }) </script> </body> </html>
<router-link to="xxxx">
でroutesに定義したpathを定義することで、リンクを表示することが出来ます。
componentが差し込まれる部分は <router-view>
です。
4.3 実践的なルーティングのための機能
URLパラメータ
/user/1
のようなURLで user_id=1 のユーザー情報を取得したりするような場合、Vue Routerではどのように実現するかを述べてくれています。
以下のような感じで対応します。
<!DOCTYPE html> <html> <head> <title>Page Title</title> <script src="https://unpkg.com/vue@2.5.17"></script> <script src="https://unpkg.com/vue-router@3.0.1"></script> </head> <body> <div id="app"> <ul> <li><router-link to="/">トップページ</router-link></li> <li><router-link to="/news/1">メンテンナスのお知らせ</router-link></li> <li><router-link to="/news/2">イベント開始</router-link></li> <li><router-link to="/news/3">あけましておめでとうございます</router-link></li> </ul> <router-view></router-view> </div> <script> const newsComponent = Vue.extend({ template: ` <div style="background:skyblue;"> <h3>こちらはID: {{ $route.params.newsId }} のニュースです</h3> <p v-if="$route.params.newsId == 1">メンテナンス開始しますよ!アクセスできないですよ</p> <p v-else-if="$route.params.newsId == 2">新イベントが開始されますよ!楽しんでね☆</p> <p v-else-if="$route.params.newsId == 3">あけましたね!正月イベントもうすぐはじまるよ!</p> </div> ` }) const router = new VueRouter({ routes: [ { path: '/', component: { template: '<div style="background:red;">トップページ</div>' } }, { path: '/news/:newsId', component: newsComponent }, ] }) new Vue({ el: '#app', router: router }) </script> </body> </html>
対応は簡単で、routesのpathでURLパラメータを渡す値を:で指定します。今回の例だと /news/:newsId
です。
URLから与えられた値は、 $route.params
から、pathで指定した名前のまま取得できいます。 今回の例だと $route.params.newsId
です。
名前付きルート
指定のルートに名前を付けられます。
前述のコードのいち部を抜粋します。
{ path: '/news/:newsId', name: 'news', component: newsComponent },
<ul> <li><router-link to="/">トップページ</router-link></li> <li><router-link :to="{ name: 'news', params: { newsId: 1 }}">メンテンナスのお知らせ</router-link></li> <li><router-link :to="{ name: 'news', params: { newsId: 2 }}">イベント開始</router-link></li> <li><router-link :to="{ name: 'news', params: { newsId: 3 }}">あけましておめでとうございます</router-link></li> </ul>
↑のコードは、URLパラメータで記載したコード同じ動きを実現します。
router.pushでの遷移
<router-link>
を使わずに遷移することも出来ます。
何らかのアクション後、自動的に遷移されるような場合に使いそうです。
new Vue({ el: '#app', router: router, methods: { linkTo: (newsId) => { router.push({ name: 'news', params: { newsId: newsId }}) } } })
<ul> <li><button v-on:click="linkTo(1)">ニュースID_1のページへ</button></li> <li><button v-on:click="linkTo(2)">ニュースID_2のページへ</button></li> <li><button v-on:click="linkTo(3)">ニュースID_3のページへ</button></li> </ul>
フック
ページ遷移前後にフックを差し込めるようです。
グローバルのフック関数
全ページ遷移に設定できるフックで、 router.beforeEach
でフックを差し込めます。
router.beforeEach((to, from, next) => { if (to.name === 'news') { alert('ニュースページへ遷移します') } next() ← これを実行しなれば、ページ遷移が実行されない })
ルート単位のフック関数
特定のルート単位でフックを差し込む方法です。
routesで定義する際に指定します。
{ path: '/news/:newsId', name: 'news', component: newsComponent, beforeEnter: (to, from, next) => { if (to.name === 'news') { alert('ニュースページへ遷移します') } next() } }
4.4 サンプルアプリケーションの実装
こちらでは、Vue Routerの機能を使って、実際にサンプルのSPAを実装します。
こちらは写経させてもらいました。
今回、使った新たなものとしては、ライフサイクルの created
を使用しています。
created
は以前の記事でも紹介している通り、インスタンスが生成され、データが初期化された後に実行されます。
ユーザー一覧遷移した際のcreated
created: function() { this.fetchData() }, methods: { fetchData: function() { this.loading = true getUsers(((err, users) => { this.loading = false if (err) { this.error = err.toString() } else { this.users = users } }).bind(this)) } }
また、watch
オプションを使用しています。
watch: { '$route': 'fetchData' },
'$route' の変更をwatchして、ルーティングの変更に伴いfetchData()が実行されるようになります。
4.5 Vue Routerの高度な機能
サンプルアプリケーションで使用されてなかったVue Routerのその他の機能が紹介されています。
便利そうだったのは、ネストしたルーティングでした。
<!DOCTYPE html> <html> <head> <title>Page Title</title> <script src="https://unpkg.com/vue@2.5.17"></script> <script src="https://unpkg.com/vue-router@3.0.1"></script> </head> <body> <div id="app"> <ul> <li><router-link to="/user/1">ユーザーID: 1</router-link></li> <li><router-link to="/user/2">ユーザーID: 2</router-link></li> <li><router-link to="/user/3">ユーザーID: 3</router-link></li> </ul> <router-view></router-view> </div> <script> const User = { template: ` <div class="user"> <h2>ユーザーIDは{{ $route.params.userId }}です。</h2> <router-link :to="'/user/' + $route.params.userId + '/profile'">ユーザーのプロフィールページを見る</router-link> <router-link :to="'/user/' + $route.params.userId + '/posts'">ユーザーの投稿ページを見る</router-link> <router-view></router-view> </div> ` } const UserProfile = { template: ` <div class="user-profile"> <h3>こちらはユーザー{{ $route.params.userId }}のプロフィールページです。</h3> </div> ` } const UserPosts = { template: ` <div class="user-posts"> <h3>こちらはユーザー{{ $route.params.userId }}の投稿ページです。</h3> </div> ` } const router = new VueRouter({ routes: [ { path: '/user/:userId', name: 'user', component: User, children: [ { path: 'profile', component: UserProfile }, { path: 'posts', component: UserPosts } ] } ] }) new Vue({ el: '#app', router: router, }) </script> </body> </html>
終わりに
サーバーサイド側のプログラムしかやってない自分にとって、とても革新的で、Vue Routerすごいなー!と思いました。
自分で作るとめっちゃ楽しいです。
さぁ次は第5章です。
がんばります。