Vue.jsをはじめるにあたって押さえておくべきこと

# 概要
この記事では、Vue.jsで開発を始めるにあたって、押さえておくべきことを記述します。
Reactで開発してきた人に向けて、「これはReactでいう〇〇」という情報も共有します。

#### [Vue.js](https://jp.vuejs.org/)

## 単一ファイルコンポーネント

- 基本的には普通のコンポーネントと同じ
- パーツを構成するために必要な HTML・CSS・JSをひとまとめにして独立した1つのファイルで扱うのが、この単一ファイルコンポーネント
- `template`、`script`、`style`で構成される
-  nameオプションは、コンポーネント名を表現します


とてもシンプルに書けば、単一ファイルコンポーネントは以下のようになります。

```example.vue
<template>
  <div class="say-hello">Hello!!<div>
</template>

<script>
  export default {
    name: 'Hello'
  }
</script>

<style scoped>
  .say-hello {
    font-weight: bold;
  }
</style>
```

## import
他のコンポーネントをimportして使用したい場合には次のように記述

- importして使用するコンポーネントをcomponentsオプションに登録する必要がある

`'./Btn.vue'`は既にあるものとします。

```example.vue
<template>
  <Btn />
</template>
<script>
  import Btn from './Btn.vue'
  export default {
    name: 'Navigation',
    components: {
      Btn
    }
  }
</script>
```

## data

- Reactでいうstate
- このコンポーネントが保持する状態を定義する

```
{
  el: '#app',
  data: {
    message: 'Hello world'
  }
}
```
- 上記のように実装すると、idが"app"のDOMの中で{{message}}というように展開する
- ただし、elオプションで指定したDOMの中でだけでしか展開できないので注意

```example.vue
<div id="app">
  <h1>{{ message }}</h1>
</div>
```

## methods
- Reactでいうハンドラ
- コンポーネント内で使用する関数はmethodsで定義 (後から、算出プロパティの`computed`について記述するので、違いについて注意してください)

```example.vue
<div id="example">
  <button v-on:click="greet">Greet</button>
</div>
```
```
<script>
  export default {
    name: 'Btn',
    methods: {
      greet: function () {
        console.log('こんにちは！')
      }
    }
  }
</script>
```

#### インラインメソッドハンドラ

- メソッド名を直接指定する代わりに、インラインJavaScript式でメソッドを指定することもできる

``` example.vue
<div id="say">
  <button v-on:click="say('hi')">Say hi</button>
  <button v-on:click="say('what')">Say what</button>
</div>
```
```example.vue
new Vue({
  el: '#example-3',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
})
```
- elオプション には、id、もしくはひとつしかないclassを指定しないといけない
- `v-on:click`クリックされたときのイベント

## computed

- 算出プロパティである


```example.vue
<div id="example">
  {{ message.split('').reverse().join('') }}
</div>
```
上記のように、たくさんのロジックをテンプレートに詰め込んでしまうとコードが肥大化し、メンテナンスが難しくなる。
そういった場合に、複雑なロジックにはcomputedを利用します。

```example.vue
<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
```
```example.vue
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    reversedMessage: function () {
      return this.message.split('').reverse().join('')
    }
  }
})
```
これで、コードが簡潔でわかりやすくなりましたね。

### computed と methods の違いについて
実は、前述しているcomputed (reversedMessage) の代わりに、同じような関数をmethodsとして定義することも可能です。
じゃあ何の違いで使い分けるの？と思うかもしれませんが、それは、**算出プロパティは依存関係にもとづきキャッシュされる**という違いがあります。
算出プロパティは、**依存するものが更新されたときにだけ再評価**されます。これはつまり、message が変わらない限りは、reversedMessage に何度アクセスしても、関数を再び実行することなく、以前計算された結果を即時に返すということです。


## v-if (条件付きレンダリング)
- 条件分岐は、`v-if`を使う
- 下記の例は、画像URLが空じゃなければimg要素を表示する例

```example.vue
<template>
  <img :src="item.image" v-if="item.image.length > 0" />
</template>
```

## v-for
- 配列からリスト作りたいときは`v-for`を使う
- mapを回す感覚
- keyにはユニークな値をセットする
- ただし、`:key`というように独特な記述方法なので注意

```example.vue
<template>
  <div class="greeting" v-for="item in greetings" :key="item.id">{{ item.text }}</div>
</template>
<script>
  export default {
    name: 'Hello',
    data: function () {
      return {
        greetings: [
          {
            id: 1,
            text: 'おはよう！'
          },
          {
            id: 2,
            text: 'こんにちは！'
          },
        ]
      }
    }
  }
</script>
```