なるはや Vue SPA入門：ファイル構成

Vue CLI3 で作成した SPA（Single Page Application）プロジェクト上で、段階的に Vue.js を学んで行きます。

[目次はこちら](https://qiita.com/tsubo/items/24df49ef2f1ba87984d1)

今回はファイル構成編です。

## 前提事項

[プロジェクト作成編](https://qiita.com/tsubo/items/50ec81ffdfb26b8bc15d) が完了していること。 

## ディレクトリ構成

ディレクトリ構成と主要ファイルを確認します。

```
vue-tutorial
├── public
│   └── index.html          ページ HTML
└── src
    ├── App.vue             レイアウト vue
    ├── components 
    │   └── HelloWorld.vue  コンポーネント vue
    ├── main.js             最初に実行される js
    ├── router.js           Vue Router の設定
    ├── store.js            Vuex の設定
    └── views               各ページ
        ├── About.vue       About ページ vue
        └── Home.vue        Home ページ vue
```

各ファイルの中身を見てみます。
ソースコード内に書かれたコメントに注目してください。
各ファイル間のつながりを理解していきましょう。

### public/index.html

このファイルが WWW ブラウザが表示するファイルです。
html ファイルが１つしかないので、Single Page APP と言います。
アプリはこのページの中身を JavaScript で書き換えることで複数ページあるように振る舞います。

```html:index.html
<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="app">
      <!-- ビルドされたファイルがここに挿入されます -->
    </div>
  </body>
</html>
```

### src/main.js

最初に実行される JavaScript ファイルです。
Vue のオブジェクトを生成して、index.html に適用しています。
Vue Router や Vuex の設定と最初に表示する App コンポーネントを指定しています。

```js:main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({               // Vue 使います
  router,               // Vue Router 使います
  store,                // Vuex ストア使います
  render: h => h(App)   // App コンポーネントを埋め込みます
}).$mount('#app')       // index.html の <div id="app"></div> に Vue を適用します
```

### src/App.vue

App.vue は全てのページに適用されるレイアウトです。
`router-link` タグでナビゲーションを作成し
`router-view` タグの部分に実際に表示されるページが差し込まれます。

```vue:App.vue
<template>
  <div id="app">
    <div id="nav">
      <!-- Vue Router を使ってページ遷移するための router-link タグです -->
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>

    <!-- Vue Router で遷移したページが router-view に表示されます -->
    <router-view/>
  </div>
</template>

<style>
  /* ここに、このコンポーネントに適用する CSS を書きます */
</style>
```

### src/router.js

URL のパスと App.vue 内の`router-view`タグに表示するページコンポーネントの関連付けを行います。

```js:router.js

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'

Vue.use(Router)

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    // path と vue コンポーネント（ページ）を関連付けます
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      // 下記の様に書くことでコンポーネントの遅延ロードが可能です
      component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
    }
  ]
})
```
### src/store.js

アプリの状態を格納しておく格納庫です。語弊があるかもしれませんが、コンポーネントを横断したグローバル変数とグローバルメソッドの格納場所と言うとイメージしやすいかもしれません。

```js:store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// Vue アプリの状態管理 まだ何も使っていません
export default new Vuex.Store({
  state: {

  },
  mutations: {

  },
  actions: {

  }
})
```

### src/views/Home.vue

Home ページのコンポーネントです。

```vue:Home.vue
<template>
  <!-- ここにコンポーネントの HTML を記述します -->
  <div class="home">
    <img
      alt="Vue logo"
      src="../assets/logo.png"
    >
    <!-- 自分で作成したコンポーネントのタグを使用することができます -->
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";

// ここに JavaScript で Vueオブジェクトを定義します 
export default {
  name: "home",
  components: {
    HelloWorld    // 自分が作成した HelloWorld を使用する
  }
};
</script>
```
### src/views/About.vue

About ページのコンポーネントです。

```vue:About.vue
<template>
  <!-- ここにコンポーネントの HTML を記述します -->
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>
```

## 動作確認

ファイル間のつながりが分かったところで、今一度動作確認をしてみます。
`yarn serve` コマンドでPC上で開発用のウェブサーバを起動して Vue アプリを実行します。

```bash
$ cd vue-tutorial
$ yarn serve
```

http://localhost:8080/ にアクセスして、ページのトップにある`Home | About`ナビゲーションメニューをクリックしてみましょう。ページが遷移するのがわかるかと思います。

## 次回

[Vue Router](https://qiita.com/tsubo/items/fe91e95e52ee82e05681)です。