vue-routerを使ってSPAの足回りを作ってみた



##はじめに
[Ateam Hikkoshi Samurai Inc. Advent Calendar 2017](https://qiita.com/advent-calendar/2017/hikkoshi)の21日目です。
本日はエイチーム引越し侍、フロントエンドグループの@hashimoto-1202が担当します。

vue.jsのライブラリである[vue-router](https://router.vuejs.org/ja/essentials/getting-started.html)を使って、非同期でページ間遷移できるナビゲーションを作ってみたので、その内容をまとめました。

環境構築からファイルの記述まで順番にまとめていくので、これからvue-routerを使ってSPA（シングルページアプリケーション）を作ってみたいという方の参考になれば幸いです。

##目次
* 今回やりたかったこと
* まずは環境構築
* ディレクトリ構成と各ファイルの記述について
* まとめ

##今回やりたかったこと
今回は　下記の2点を勉強することを目的にナビゲーションを作ってみました。
* vue-routerを使ってみる
* vueファイル（単一ファイルコンポーネント）をwebpackでビルドする環境を作る

[作例はこちら](https://takahiro-hashimoto.github.io/vueRouter/#/)

##まずは環境構築

今回は上記でも触れたとおり、vueファイル（単一ファイルコンポーネント）をwebpackでビルドして、ナビゲーションを作りました。

最低限必要なpackageを落としてくるとpackage.jsonファイルは下記のような感じになります。
vue,vue-routerのほか、vueファイルをビルドするために、vue-loaderやvue-template-compilerのインストールも必要です。

```json
{
  "name": "vueRouter",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-polyfill": "^6.26.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.7.1"
  },
  "dependencies": {
    "vue": "^2.5.11",
    "vue-loader": "^13.6.0",
    "vue-router": "^3.0.1",
    "vue-template-compiler": "^2.5.11"
  }
}
```

一から環境を整えていく際には下記の記事がわかりやすいと思います！
[はじめてのWebpack](https://qiita.com/cheez921/items/266b1b4534b6111a9686)

続いてwebpack.config.jsの記述を見ていきます。

```js
const webpack = require('webpack');

module.exports = {
  entry: `./src/main.js`,
  output: {
    path: `${__dirname}/dist`,
    filename: 'bundle.js'
  },
  devServer: {
    contentBase: __dirname + '/',
    port: 8081
  },
  module: {
    loaders: [
      {
       test: /\.vue$/,
       loader: 'vue-loader'
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query:{
          presets: ['es2015','stage-0']
        }
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['.js', '.vue', 'vuex', '.json']
  }
};

```

##ディレクトリ構成

環境構築が済んだら、ナビゲーション作成に必要なファイルを作っていきます。今回は下記のようなディレクトリ構成でファイルを作成しました。どのようなディレクトリ構成がいいのかよくわからなかったので、vue-routerの使い方について書かれているネットの記事をいくつか参考にさせていただきました。

```
├── app.vue
├── main.js
├── router.js
└── pages
    ├── top.vue
    ├── about.vue
    └── contact.vue
```

main.jsでは、Vueクラスのインスタンスを作成。対象となるHTML要素などを記述しています。

``` javaScript
import Vue from 'vue';
import router from '../src/router';
import App from '../src/App.vue';

new Vue({
  el: '#js-app',
  router,
  render: h => h(App)
});
```

今回の肝になるrouter.jsでは、必要なファイルをそれぞれ読み込み、pathの定義を行います。

``` javaScript
import Vue from 'vue';
import VueRouter from 'vue-router';
import Top from './pages/Top';
import About from './pages/About';
import Contact from './pages/Contact';

Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    component: Top
  },
  {
    path: '/about',
    component: About
  },
  {
    path: '/contact',
    component: Contact
  }
];

const router = new VueRouter({
  routes,
  mode: 'history'
});

export default new VueRouter({routes});
```

App.jsはナビゲーション部分のtemplateを記述。<router-view></router-view>の部分にリンク先と紐付いたtemplateが描画されます。

```html
<template>
  <div>
　　　　  <div class="header">
      <router-link to="/">
        top
      </router-link>
      <router-link to="about">
        about
      </router-link>
      <router-link to="contact">
        contact
      </router-link>
    </div>
    <div class="content">
      <router-view></router-view>
    </div>
  </div>
</template>

```

pagesフォルダの中には、ナビゲーションに紐付いて描画されるファイルが格納されています。

```html
<template>
  <div>
    ここはTopページです。
  </div>
</template>

```

上記のようなファイル群をwebpackでbuildし、コンパイルされたファイルを読み込ませれば、vue-routerを用いたナビゲーションが完成です。

## まとめ
簡単ではありますが、vue-routerを用いてヘッダーナビゲーションを作成する手順をまとめていきました。
今回はvue-routerを使ってページ間の遷移をさせるだけでしたが、vue.jsを用いてコンテンツを実装すれば、ちゃんとしたSPAのサイトを構築することができますので、実際に手を動かしてみて、その一歩を踏み出していただければと思います。

明日はエイチームコネクトのエンジニア、@mori_moriが「ビットコインの裁定取引の自動化」に関する記事を書いてくれます。お楽しみに。


## 追伸
株式会社エイチーム引越し侍では、一緒にサイト改善をしてくれるWebエンジニアを募集しています。エイチームグループのエンジニアとして働きたい！という方は是非、以下のリンクから応募してください。

皆様からのご応募、お待ちしております！！

[エイチームグループ採用サイト（Web開発エンジニア職）
](http://www.a-tm.co.jp/recruit/requirements/career/lifestylesupport-webengineer/)