Vue.js入門

[社内勉強会](https://leccafe.connpass.com/event/69664/)の時のメモです。
ざっくりとVueを触った手順とできたこと。

## 環境準備

※ Nodeのインストールが必要 v8で動作確認（古いと動かない場合がある）

1.vue-cliのインストール
`$ npm i -g vue-cli`

2.vueコマンドが使えるようになったか確認（バージョンが出たらOK）
`$ vue --version`

3.Vue.jsのテンプレートを利用してプロジェクトを作ってみる。
`$ vue init webpack-simple my-project`
プロジェクトネームとか聞かれるのでとりあえずエンターを押しまくる。

`$ cd my-project`
`$ npm i`

以上のコマンドで、my-projectフォルダにVueのテンプレートが一式落ちてきていろいろ試してみることができる。

4.確認用ブラウザの立ち上げ
`$ npm run dev`

### App.vueの中身

```html
<template>...</template> 　HTMLを記述
<script>...</script> 　　　jsを記述
<style>...</style>　　　　 CSSを記述
```

App.vueの中身を見ると、vueファイルの構造は大きく３つに分かれていることがわかる。


## データバインディング
Vue.jsではHTML内で`{{...}}`を用いて記述した箇所と、script内のDataに記述した値がつながっている。

```html
<h1>{{ msg }}</h1>
<a :href="url">link sample</a>
```

```html
<script>
export default {
  name: 'app',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      url: 'https:chatbox-inc.com'
    }
  }
}
</script>
```
タグの属性に値を入れたい時は属性名の前に`:`をいれる。

## イベントハンドリング

### サンプル1_カウンターボタン
```html
<a @click="countUp">eventButton</a>
<p>{{counter}}</p>
```
```html
<script>
export default {
  name: 'app',
  data () {
    return {
      counter: 1
    }
  },
  methods: {
      countUp() {
          this.counter++;
      }
  }

}
</script>
```
処理に関することはmethodsに記述する。
これで`eventButton`がクリックされると`{{counter}}`の数字が増える処理が行われる。

### サンプル2_要素の表示/非表示
```html
<a @click="toggle">message Show Button</a>
    <p v-if="showMessage">message</p>
```
```html
<script>
export default {
  name: 'app',
  data () {
    return {
      showMessage: true
    }
  },
  methods: {
      toggle() {
          this.showMessage = !this.showMessage
      }
  }

}
</script>
```
`message Show Button`をクリックするとmessageを出したり消したりできる。

## コンポーネントの利用
コンポーネントは.vueファイルで作成することができる。

▼ 新たに作ったExample.vueにサンプルコンポーネントを定義する

```html
<template>
    <div>
        サンプルコンポーネント
    </div>
</template>
```

別ファイルで定義したコンポーネントの参照はimport文を用いて行うことができる。

▼ App.vueでExample.vueを参照する

```html
<script>
import ExampleComponent from './Example.vue'
</script>
```

import後名前をつけて登録することで<template>の中で利用可能なタグとなる。

▼ App.vueで読み込んだExampleComponentをコンポーネントとしてmyComponentタグに登録する。

```html
<script>
import ExampleComponent from './Example.vue'
    export default {
        components: {
          myComponent: ExampleComponent
        }
    }
</script>
```
▼ 登録したコンポーネントを使用する

```html
<myComponent></myComponent>
```
↓ HTML結果

```html
<div>
    サンプルコンポーネント
</div>
```

### Vue.jsによるSPA開発
JSアプリケーションにおける画面状態遷移では、ルーティングのライブラリを用いた手法が一般的に使われる。
Vue.jsではVueRouterと呼ばれるルータライブラリを用いてSPAを構築するのが一般的。

### 1.VueRouterをインストールする
`npm i vue-router --save`

### 2.`src/main.js` にVueRouterの記述を行う

▼ main.js

```main.js
import VueRouter from 'vue-router'
Vue.use(VueRouter)

var router = new VueRouter({
    routes : [
      // ここにルートを記述
    ]
})
```

### 3.ルートを記述する

```js
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// インポートして別ファイルから参照
import ExampleComponent from './Example.vue'
import Post from './Post.vue'


var router = new VueRouter({
    routes : [
　　　　// アドレスと表示させたいコンポーネントを紐付けて記述する
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar },
      { path: '/', component: ExampleComponent },
      { path: '/post/:id', component: Post }
    ]
})
```

### 4.ルートを利用する

▼ src/App.vue

```html
<template>
　<router-link to="/">top</router-link>
        <router-link to="/foo">foo page</router-link>
        <router-link to="/bar">bar page</router-link>
        <router-link to="/post/2355">投稿2355</router-link>
        <router-link to="/post/0655">投稿0655</router-link>

        <router-view></router-view>
　　　　
</template>
```
<router-view>の設置場所でURLに応じで指定されたコンポーネントと切り替わる。
ルートのURL切り替えには`router-link`要素が利用できる。hrefではなくto要素にルートのURLを記述する。


### 本番用サーバにアップロード
ブラウザでvueは認識できないので、
`npm run build`によって吐き出される`dist/build.js`とHTMLの２つのみサーバにUPすればOK.


### 追記（src/Post.vue）
Post.vueをうっかり記述忘れてたみたいなので、とりあえず補足という形になりますが記載しておきます。
▼ src/Post.vue

```html
<template>
    <div>
        <h1>{{title}}</h1>
        <p>投稿のID: {{$route.params.id}}</p>
    </div>
</template>

<script>
    export default {
        data() {
            return{
                title: "記事のタイトル"
            }

        }
    }
</script>
```