Vue-routerを使って、SPAをシンプルにはじめてみる

## はじめに

``Vue-router``を使ってシンプルなSPA(Single Page Application)的なサイトを作ってみる。なかなかシンプルにやりたいことだけやれる説明サイトが見つからなかったのでまとめておきます。
やりたいことは、最初に画面がでてきて、画面内のリンクをおしていくとどんどん次のページへ進んでいくという単純な画面遷移を``Vue-router``を使って実現すること、それだけです。

> むかしはこれだけでもできたら、すぐに"アドベンチャーゲーム"作れるなー とか思いましたが、最近アドベンチャーゲームというジャンルもなかなか聞かなくなりましたね.....

説明は、大事なポイント以外は省略してやりたいことに一直線でいきます。

> (2018.11)
> しばらく放置した結果Vueのバージョンが変わり動かないサンプルコードになっていたので修正しました。。

## Vue および Vue-router のインストール
なにはともあれインストールしてみる。今回さくっとやりたいので``Vue-cli``というものでテンプレートも作っちゃったあとに、Vue-router化します。

```
$ npm -g install vue-cli
$ vue init webpack my-project
```

質問がいくつか出てきますが適当にリターン/Enter連打でこたえていきます。
ここでeslintやtestフレームワークも入りますので、本当はそういうところもきちんと見てほしいところですが、、、今回はシンプルに始めるのが目的なので目をつぶります。

```
$ cd my-project
$ npm run dev
```

これでいったんVue.jsが動くまできました。 ``http://localhost:8080/`` で動作確認できます。
手前味噌的ですが、このあたりの詳しいことは [こちらの投稿](https://qiita.com/567000/items/dde495d6a8ad1c25fa43) にかいてあります。

ここまでで ``Vue-router``も一緒にインストールされた状態で環境のセットアップができました。

## 目的のソースになるように大改造

説明略！で説明します。

まずはソースツリーは以下のようになります。
説明必要なものだけ書いています。

```
 ./build/
 ./config/
 ./index.html ← 後で書き換えるメインのHTML
 ./node_modules/
 ./package.json
 ./package-lock.json
 ./README.md
 ./src/
     ./App.vue
     ./assets/
     ./components/
        ./Hello... ← 後で書き換える実際に表示するページ
     ./main.js
     ./router/
         ./index.js ← 後で書き換えるルーティング(画面遷移)の設定
 ./static/
 ./test/
```

まずはHTMLです。

```index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>たいとる</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
```

ポイントは、``<div id="app"></div>``です。コメントも(英語で)書いてありますがここにページが挿入されます。

なのでヘッダやフッタを共通化したければここのindex.htmlに書いてしまうと楽です。
次に、``main.js``です。実際は、``Vue-cli``のお力でうまいことビルドされて``app.js``になって``index.html``に読み込まれるものです。

```src/main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
```

これはこのままでいいです。特に気にすることないですが、このスクリプトでHTMLの`#app`を書き換えるんだな、ということくらいは念頭に置いておく。

***
ただ、1点気にしておいてほしいのは、もとの`index.html`では、`script`で何も読み込まんでいませんよね？ HTMLに書いていないのに勝手にスクリプトが読み込まれるなんて超常現象はプログラムでは絶対に起きません。ということはどこかで必ず書かれているはずです。
種明かしをすると、`npm run dev` を実行すると、

```
  src/main.js を app.js にコンパイル
  index.html に <script type="text/javascript" src="/app.js"></script>　行を追加
```

という動作が起きます。実際のブラウザは、この`app.js`が組み込まれたHTMLが動くため、`src/main.js` が動作します。
実際に運用する時には、`npm run build` というのがあるのでそちらで静的なコードを作成します。
***

話を戻して、次に、お待ちかねのルーティングです。
もとのソースを下記のソースで上書きしてしまいます。

```src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'

import page1 from '@/components/page1'
import page2 from '@/components/page2'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      component: page1
    },
    {
      path: '/page2',
      component: page2
    }
  ]
})
```

なんとなくわかると思いますが、``path`` ``/``でアクセスされると``page1.vue``の内容を表示します。 ``/page2``でアクセスされると``page2.vue``の内容を表示する、という設定が書かれています。

では、具体的な``page1.vue``の中身です。

```html:src/components/page1.vue
<template>
  <div>
    <p>
      ここはページ１です。
    </p>
    <router-link to="/page2">Go to page2</router-link>
  </div>
</template>

<script>
</script>

<style>
</style>
```

次に、`page2` の中身。

```html:page2.vue
<template>
  <div>
    <p>
      ここはページ２です。
    </p>
    <router-link to="/">Go to page1</router-link>
  </div>
</template>

<script>
</script>

<style>
</style>
```

Vue.jsのコンポーネントです。好きなHTMLを書いて、好きなスクリプト、CSSを書いてください。

最初に説明した``index.html``の``#app``にこれが挿入されます。

ここでもポイントだけ。 大事なのは``<router-link to="/page2">Go to page2</router-link>``です。これで``/page2``へのリンクがはられます。このリンクをクリックすることで``page2``へ遷移します。遷移といっても実際は ``index.html``の``<router-view></router-view>``が``page2.vue``のHTML(``<template>``)に置き換わることになります。

これを繰り返していくことで SPA で画面遷移を進めていくことが出来ます。

とりあえずこれだけわかっていれば `Vue-router` を簡単に遊んでみることはできると思います。。