【Vue.js】爆速でSPAを作る

シングルページアプリケーションが流行っているらしいので、今頃便乗して簡単にできると言うVue.jsを使ってSPAを作ってみます。

Vueとか何もわからないけど、とりあえずやってみたいという人はぜひ参考にしてください。
ただ、多少触ってみてからSPAに挑戦するのをおすすめします。

超簡単にですが前回まとめた記事がありますのでこちらをご覧ください。
https://qiita.com/nagimaruxxx/items/279ca1c57a8ec8325558

## 開発環境

**dockerコンテナ内とかではなくMac上で行います**(ここで間違えてつまづいた人)
- macOS High Sierra
- node.js 10.11.0
- npm 6.4.1

## Vue.jsって？
JavaScriptのフレームワークです。
特徴としてあげられることは
・MVVMフレームワーク
・学習コストが低い
・双方向データバインディング
・高速である
などなど、強みの多い人気のフレームワークですね。

## 目標
コンテンツの中身は気にせず、ただ単にページ遷移なしで複数のHTMLファイルが閲覧できるようにする！
スクロールして別のコンテンツがそのまま表示されるイメージ！

## 導入
#### nodebrewのインストール
Node.jsのバージョン管理するためのツールです:relaxed:

```sh:ターミナル
$ curl -L git.io/nodebrew | perl - setup
```

パスを通してねっていうメッセージが表示されるので、パスを通しましょう。

```sh:ターミナル
$ cd
$ vi .bash_profile
```

```sh:.bash_profile
# 以下の文を追加
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

```sh:ターミナル
# .bash_profileの再読み込み
$ source .bash_profile
# ヘルプ画面が表示されたらOK！
$ nodebrew
```

#### node.jsとnpmをインストールする
:warning:　**node.js 8.9以上でないとVue CLI3は動かないので気をつけましょう**

```sh:ターミナル
# 最新版をインストール
$ nodebrew install latest
$ nodebrew use latest
# それぞれバージョンが表示されればOK！
$ node -v
$ npm -v
```

ここでつまづいたらパスが通ってないとかだと思うので調べてみてください。

### Vue CLIのインストール
Vue CLIとは、Vue.jsでアプリケーションをつくるための、コマンドラインインタフェース(CLI)にもとづく開発ツールです。

```sh:ターミナル
$ npm install -g vue-cli
```

### プロジェクトを作成する
プロジェクトを置いておく場所に移動して、

```sh:ターミナル
$ vue init webpack single_page_application
# ...
# ...
# ここでプロジェクト名や作者名を入力しますが、デフォルトでYesで大丈夫です。

$ cd single_page_application
$ npm run dev
```
とすると、

```sh
Your application is running here: http://localhost:8080
```
と表示されるはずです！
私の場合8080番はdockerで使用しているので、8081番が割り振られました。親切〜:pray_tone2:
で http://localhost:8080 にアクセスすると、
![スクリーンショット 2018-11-06 13.00.14.png](https://qiita-image-store.s3.amazonaws.com/0/246277/55e3c4db-9c34-465f-e9e0-4ed07a087517.png)
こんな感じでサンプルが表示されます。

---

ちなみに```$ npm run dev```を実行している間に
**1.ローカルサーバーを立ち上げる**
**2.src/main.jsをapp.jsにコンパイルする**
**3.index.htmlからapp.jsを読み込む**
という動作が行われています。

ですので```$ npm run dev```を停止するとアクセスできなくなるんですね。

ここまでできれば、環境構築は終わりです！　　さて、次！:point_right_tone2:

##完成イメージ
![ydndm-6qojz.gif](https://qiita-image-store.s3.amazonaws.com/0/246277/b1336894-5e54-7ecb-c07d-d88991bd47b4.gif)
簡単ですが、こんな感じでクリックでページ遷移せずにコンテンツの中身が変わる感じで作っていきます。


## 各ファイルの役割を理解する
自動でファイルが作られたと思うので、各ファイルの説明をしていきます。

####全体の流れをみる
```html:/index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>single_page_application</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
```
まずindex.htmlから。
このファイルにはほとんど要素が書かれていません。```<div id="app>```の中にコンテンツが入るのですが、その中身は別のファイルで設定していきます。

####コンテンツの部品を作っていく
```vue:/src/components/page1.vue
<template>
   <p>ここはトップページです。</p>
</template>

<script>
</script>

<style>
</style>
```
と、こんな感じでpage2, page3と同じページを増やしていきましょう。
パッと見て気づくと思いますが、ここでjsやcssの設定もできます。
これがページが切り替わる時に表示される部品となります。


####ルーティングをする
```javascript:src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import page1 from '@/components/page1'
import page2 from '@/components/page2'
import page3 from '@/components/page3'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      component: page1
    },
    {
      path: '/page2',
      component: page2
    },
    {
      path: '/page3',
      component: page3
    }
  ]
})
```
先ほど作ったvueファイルのルーティングを設定します。
```@import```でファイルの読み込み、

```vue:
routes: [
    {
      path: '/',
      component: page1
    },
```
でパスの設定をしています。/(インデックスページ)ではpage1.vueを読み込みますという意味ですね。

####コンテンツを設置する
```vue:src/App.vue
<template>
  <div id="app">
    <div id="header">
      <!--リンクタグを生成します。-->
      <router-link to="/">top</router-link>
      <router-link to="/page2">about</router-link>
      <router-link to="/page3">contact</router-link>
    </div>
    <!--上記のリンクタグで設定したコンポーネントが表示される場所です。-->
    <router-view></router-view>
  </div>
</template>

<!--コンポーネントの名前を定義します。-->
<script>
export default {
  name: 'App'
}
</script>

<!--スタイルの指定をします-->
<style>
body {
  margin: 0;
}

#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#header {
  height: 40px;
  background: white;
  box-shadow: 0px 3px 3px rgba(0,0,0,0.1);
  display: flex;
  justify-content: center;
  align-items: center;
}

#header a {
  text-decoration: none;
  color: #2c3e50;
  margin: 0 10px;
  padding: 3px 10px;
  background: #5ccebf;
}
</style>
```

こんな感じで簡単なSPAを作成することができました。
これを応用すれば、色々なことができそうです！