vue-cli2で個人事業のページを作った

### 概要
毎年ページを更新しているのですが、今回はvue.jsが気になっていたのでvue-cliを使ってホームページを作ってみることに。その時に使ったものや、やったことなどのまとめになります。
vue-cliは3が使えるようになってましたが、情報が少なそうだったので2でやりました。（ビビり）

開発環境 : windows, bitbuket, vue-cli2.9.5
本番環境 : apache2, centos6

### できたもの

https://codelike.info

<img jsname="uLHQEd" class="SzDcob" src="https://lh3.googleusercontent.com/1nTMr4iMP0OIkMa1a8lnNLyPHcXmUCTaqSzP1FzJC7ddy9jorR8EISks0MQZmaEG2o49JqPKkjhywBS7Puh0ETeQrWtRTIqaup42EazTwFDJgXVqCmbc_eCcAPXndBTro42o2n6w0PZizb5DaDpCMUB1Zgxx2pQ9JUZKSNcUW4bEJVN6OQe5XylZUdy8am1tpKc_HPMWEnXXWnh3PLUtQqCH2t4cuImDW0ks_RhhakkXt9sWks0Aldpi6bfu6JY1YgmoYG1oDAbpe6BeR7IMNw6Ni02qJvStUJJJKWxLtIFzXJ2Vh4tegfm5pndeFBxxQ22gQOsHzWglIrh2nXoWDtUQ953MUVD_NVu3PKGclrsQ7E4ywI-SW_ROb5DXah3QugIrsBUI_Dgvi0WZSoAfgjnBobhey1hqUscyNkpFYpHhkpEL7Yu2k_bL9L4iuLH8XVeRO1yXs4XDHcAoGN0uQ1MMiaAuWzmTAWMDuzUUelGJ0BkiQdvkF-WKa0zwESUyccoykRUytslpBMcnZl5EJRKaDQXb7NvqCeD8rj9UYz7dK7W_hyV7jPkKp1zZAhbMU9gvFBRH3VYUGN1c4fmOor6-ejLazNxEbJdPV_hiaYlL0mJY4wUaphcgsCD4PS9abUmU5ARToMPtfAWCpNp4csb5OMYkUwu3=w1082-h865-no" style="transform: translate3d(0px, 0px, 0px) rotate(0deg);" aria-label="写真 - 横向き - 2018/06/21 23:23:41 ">

### プロジェクトを作成 && 使うモジュールのインストール！
とりあえずvue-cliをインストール！:raised_hands_tone1:

```shell
npm install -g vue-cli
```

プロジェクトを作成する。特に設定は変えずにEnterで進めた。

```shell
 vue init webpack codelike2018
```

レスポンシブ対応などを楽にするためbootstrap4とアイコンが使いたかったのでopen-iconicを入れた。

```shell
bower install bootstrap4 --save
bower install open-iconic --save
```

そのままだと、bower_componentが変なところに行っちゃうので、.bowerrcを下記のように設定
.gitignoreにも/src/libraryを追加してgit管理されないようにした。

```json
{
  "directory":"src/library"
}
```

npmで下記をインストールした。

```json
"dependencies": {
  "axios": "^0.18.0", /*--wpとのajax通信のため--*/
  "vue-carousel": "^0.8.1", /*--トップページがさみしいのでカルーセルで画像流す用--*/
  "vue-js-modal": "^1.3.15", /*--モーダル画面を表示するため(簡単につかえて便利)--*/
}
```

### ソースを書いてみる

##### ページのルーティングを作る
`src\router\index.js` にURLルーティングのためのファイルが出来上がるので、そこにアクセスされたときに対応するコンポーネントをぱぱーっと書く。

```javascript:src\router\index.js
import Vue from 'vue'
import Router from 'vue-router'
import Top from '@/components/Top'
import About from '@/components/About'
import Profile from '@/components/Profile'
import Service from '@/components/Service'
import Contact from '@/components/Contact'
import Blog from '@/components/Blog'
import NotFound from '@/components/NotFound'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Top',
      component: Top
    },
    {
      path: '/about',
      name: 'About',
      component: About
    },
    {
      path: '/service',
      name: 'Service',
      component: Service
    },
    {
      path: '/profile',
      name: 'Profile',
      component: Profile
    },
    {
      path: '/contact',
      name: 'Contact',
      component: Contact
    },
    {
      path: '/blog',
      name: 'Blog',
      component: Blog
    },
    {
      path: '/404',
      name: 'NotFound',
      component: NotFound
    },
    {
      path: '*',
      redirect: { name: 'NotFound' }
    }
  ]
})
```

##### レイアウトを作る
基本となるレイアウトは `src\App.vue` に記載する。
`router-viewタグ` の箇所にそれぞれのコンポーネントの内容が反映される。
transitionタグで囲むことで、画面遷移するときにclassが付加されるので、cssアニメーションを書くことができる。
メニューはSmartphoneNav.vueとSideNav.vueコンポーネントに分けてみた。
コンポーネントを呼ぶときは `imoprt` してcompornentsに列挙する。

```vue:src\App.vue
<template>
  <div id="app">
    <div class="d-md-none">
      <div class="row">
        <div class="col-12">
          <SmartphoneNav />
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-2 d-none d-md-block">
        <nav class="col-md-2 h-100 sidebar" style="position:fixed;">
          <SideNav />
        </nav>
      </div>
      <div class="col-md-10 col-xs-12 col-sm-12">
        <transition name="fade">
          <router-view />
        </transition>
      </div>
    </div>
  </div>
</template>

<script>
import './library/bootstrap4/dist/css/bootstrap.css'
import './library/open-iconic/font/css/open-iconic-bootstrap.css'
import SideNav from './components/SideNav'
import SmartphoneNav from './components/SmartphoneNav'

export default {
  name: 'App',
  components: { SideNav, SmartphoneNav }
}
・・・省略・・・
```

#### それぞれのページコンポーネントに内容を記載する
今回は下記のような感じでコンポーネントを作ってみました！
長くなるので詳細は省略。

- src\components\About.vue
- src\components\Blog.vue
- src\components\Contact.vue
- src\components\NotFound.vue
- src\components\Profile.vue
- src\components\Service.vue
- src\components\SideNav.vue
- src\components\SmartphoneNav.vue
- src\components\Top.vue

#### モジュールの使い方と工夫したところ
##### vue-carousel
カルーセルが簡単に実装できます。下記のような感じで書きました。

```vue:Top.vue（一部）
    <carousel :per-page="1" :loop="true" :autoplay="true">
      <slide>
        <img src="../assets/topimg_1.jpg" class="w-100 h-100">
      </slide>
      <slide>
        <img src="../assets/topimg_2.jpg" class="w-100 h-100">
      </slide>
      <slide>
        <img src="../assets/topimg_3.jpg" class="w-100 h-100">
      </slide >
    </carousel>
```

`import { Carousel, Slide } from 'vue-carousel' して上記のような感じでtemplate書くと
勝手にカルーセルしてくれます。
per-pageがスクロールするページ数（初期は２つのslideが一緒になっている) loop=trueでループしてくれる。autoplayは自動スライド。

##### vue-js-modal
モーダル画面が簡単に実装できます。

```vue:Contact.vue（一部）
    <modal name="send_message" id="send_message" width="80%" height="200">
      <div class="send_message_box">
        お問い合わせありがとうございました、送信完了しました。<br>
        内容確認後、折り返し連絡いたします。<br>
        <button class="btn btn-primary btn-block mt-5" v-on:click="closeDialog">閉じる</button>
      </div>
    </modal>
```
main.jsに読み込む設定を書いとけば、後は上記のようにテンプレートに記載して、
methodsで呼ばれるメソッドに `this.$modal.show('send_message')` みたいに書くとモーダルとして開きます。明示的にモーダルを閉じるときは `this.$modal.hide('send_message')` と書けばOK

##### axios
ajax通信を行うために入れました。
wordpress rest apiを使ってblogの内容を一部とってきて、表示させてみました。

```vue:Blog.vue（一部）
  mounted () {
    this.$modal.show('pre_load')
    axios.get('http://blog.codelike.info//wp-json/wp/v2/posts').then(response => (this.blogData(response.data)))
  }
```
mountedに上記のように書きました。loadモーダル画面を表示してaxiosでデータを取得。
あとはtemplateのほうで、 `v-for`属性を使用してループさせて表示させています。

### 困ったこと
npm run buildしてbuildしたときに、styleの優先度が変わったのか画面が崩れたりした。。
あまり使いたくないけど !importantをそれぞれつけることで解決した。
この辺はよくわからなかった:weary:

### その他
#### google analyticsの設定とかページタイトルとか
index.htmlに書いておけばOK。

#### faviconどうしたか
static配下に置いて、index.htmlに読み込み設定書けばOK。

#### 本番環境で動かすとき
`npm run build` コマンドで /dist/にindex.htmlと共にファイルがまとめられるので、それをサイトのルートフォルダにおけばOK

### 所感
angularを使うより手軽に使えて、自由度が高い気がしました。
モダンjs(ES6)に弱いので、ちょっと戸惑いましたorz
コンポーネントに分けることで、管理もしやすそうだしよかったです。
あんまり手をいれることはなさそうですが・・・:innocent: