【Vue.js応用】vue-routerでSPAの足回り構築
2015/10/31追記
この記事はVue.js@0.12.1を元に書かれています。最新版は1系統で書式に大きな変更がありますでのご注意ください。
Vue.jsを0.12.1から1.0.3にアップデートした際にハマったこと - 俺、サービス売って家買うんだ
さて、案件でVue.jsを使うのも手に馴染んできたのでSPA(Single Page Application)の足回りを試しに構築してみようと思います。
きっかけはこのツイート
vue-router 0.5.2 released: https://t.co/LyKylD32pq And the documentation is now complete: http://t.co/Su8GsNwfOD
— Vue.js (@vuejs) August 23, 2015
公式ドキュメントのBuilding Larger Appsの項にも出てきており、使えそうな感じだしせっかくなので遊んでみました。
http://vuejs.org/guide/application.htmlvuejs.org
For Single Page Applications, it is recommended to use the offical vue-router library, which is now in technical preview. For more details, please refer to vue-router’s documentation.
vue-routerとは
Vue.jsオフィシャルのルータで、Vue.js 0.12.10+から利用可能です。
主な機能としては。
- 入れ子可能なルートマッピング
- ルーティング時にワイルドカードやクエリパラメータ
- Modular、Components-baseのルーティング
- HTML5 history APIで動作
- etc
構築に必要なもの
webpack + vue-loader
Components単位で分けてそれを組み合わせて実装していきます。以前興味本位でjspmの記事を書いたけどトレンドを見てみると微妙なので今日はwebpackで。
三択ですね 笑
babel-loader
せっかく勉強なので、ES2015で書きます。
Vue.js + vue-router
Vue.jsだけだとrouter機能を持っていないのでvue-routerを使って表現します。
とりあえずサンプルを組み合わせて作ってみた
Vue.jsの開発者であるEvan Youさんが作っていた以下のサンプルを組み合わせながら簡単なSPAにしてみました。
(見た目は読んだサンプルまんまです。すいませんorz)
参考
- GitHub - vuejs/vue-loader-example: Example using vue-loader with Webpack.
- GitHub - vuejs/vue-router: The official router for Vue.js.
確認したかったこと
- ディレクトリ構成
- routingの方法
- urlからパラメータの受け渡し方法
- レンダリング方法
ディレクトリ構成
ここはサンプルと少し変えて以下の様にしてみました。
(Components-baseって言われてるのにpageとか作るの微妙かな・・・)
. ├── app.vue # アプリケーション大枠(iOSアプリで言うUINavigationController) ├── components # プロダクト全体で使うコンポーネント │ ├── a.vue │ ├── b.vue │ └── modal.vue # この間作ったモーダル ├── main.js └── pages # ページ自体この中にコンポーネントを入れてページを組み上げてみた ├── bar.vue ├── foo.vue └── home.vue
routingの方法
一般的なWAFのrouterとほとんど同じ。
my-first-vue-router/main.js at master · hazumu/my-first-vue-router · GitHub
const Vue = require('vue') const VueRouter = require('vue-router') // 忘れず! Vue.use(VueRouter) const router = new VueRouter({ history: true, saveScrollPosition: true }) router.map({ '/': { component: require('./pages/home.vue') }, '/home': { component: require('./pages/home.vue') }, '/foo': { component: require('./pages/foo.vue') }, '/bar/:id': { component: require('./pages/bar.vue') } }) const App = Vue.extend(require('./app.vue')) router.start(App, '#app')
公式のサンプルではroutingのネストもできるようですね。
もはやサーバーサイドのそれと何も変わらない・・
https://github.com/vuejs/vue-router/blob/dev/example/advanced/route-config.js
// nested example '/user/:userId': { component: require('./components/user/index.vue'), subRoutes: { // matches "/user/:userId/profile/:something" 'profile/:something': { component: require('./components/user/profile.vue') }, // matches "/user/:userId/posts" 'posts': { component: require('./components/user/posts.vue') }, // matches "/user/:userId/settings" 'settings': { component: require('./components/user/settings.vue') } } },
routerのオプション一部抜粋
history
- default: false
- history.pushState() と history.replaceState() でヒストリー管理するか?
- デフォルト動作は#!(ハッシュバング)
saveScrollPosition
- default: false
- HTML5 history modeだけで動作
- ページ遷移した時に前のページのスクロール位置を保存するかどうか
その他
http://vuejs.github.io/vue-router/options.html
urlからパラメータの受け渡し方法
this.$routeから取得できます。
my-first-vue-router/bar.vue at master · hazumu/my-first-vue-router · GitHub
data () { return { msg: 'This is Bar!', id: this.$route.params.id } },
レンダリング方法
自分でcomponentsに名前を付けなくてもルートとマッチしたコンポーネントが<router-view>に表示される。
<router-view></router-view>
まとめ
よかった
- componentsで作り、足回りさえ固まるってくるとネイティブのアプリを作ってる感じで作れる
- この手のやつって足回りを作るのが一番時間かかる気もするけど。
- ES2015のmoduleとVueのcomponentsの相性がいい
考え中
- xhrのところをどうしようかな。作成者のサンプルではservice層を置いている
- これでxhrの機能が入っちゃうとまんまAngular..
- transition周り
- ページ遷移のアニメーションのためのhookはありがたいけどFWレベルでは必要なのか若干懐疑的
ちょろっと入れてData-bindingで便利みたいなVue.jsでしたがここまでやるとかなりなんでもできますね。 こっそりと今後に期待してます。
(∩`ω´)⊃)) オラッオラッ
関連書籍
- 作者: 掌田津耶乃
- 出版社/メーカー: 秀和システム
- 発売日: 2016/09/16
- メディア: 単行本
- この商品を含むブログを見る
Practical Vue.js: Reactive Components for Modern Web Interfaces (English Edition)
- 作者: Daniel Schmitz
- 発売日: 2016/07/08
- メディア: Kindle版
- この商品を含むブログを見る