5分でわかるVue.js基礎の基礎

# 環境
[JSFiddle](https://jsfiddle.net/)でVueを選択するだけでVue.jsを試し打ちできる環境が作れます。
![スクリーンショット 2019-08-25 22.38.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/1d799b95-3331-a376-03b4-eb74b5be3687.png)

# 基本構文
## Vueインスタンスの生成
new VueでVueインスタンスを生成し、その中のel要素で、html側のどの部分を対象としてVueを使用するか定義することができます。

```html:html
<div id='app'>
</div>
```

```js:js
new Vue({
  el: '#app'
})
```

## 変数
### data
Vueインスタンス内のdata要素に変数を定義することができます。格納した変数はhtml側で`{{ }}`をつけると呼び出すことができます。

```html:html
<div id='app'>
  <p>{{ message }}</p>
</div>
```

```js:js
new Vue({
  el: '#app',
  data: {
    message: 'Hello VueJS!'
  }
})
```

<img width="307" alt="スクリーンショット 2019-08-25 17.34.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/a143ebf2-daa0-a5e1-d234-4f4148fd3675.png">


### computed
関数の戻り値を変数として利用する場合はVueインスタンス内のcomputed要素に定義します。

```html:html
<div id='app'>
  <p>{{ datetime }}</p>
</div>
```

```js:js
new Vue({
  el: '#app',
  computed: {
    datetime: function(){
      return new Date();
    }
  }
})
```

<img width="437" alt="スクリーンショット 2019-08-25 17.36.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/607dae6a-bcc8-54a3-ab9f-08f03d3c2372.png">


## 関数
Vueインスタンス内のmethods要素に関数を定義することができます。html側に関数名を記載することで呼び出すことができます。（`@click`については後述）

```html:html
<div id='app'>
  <p>{{ message }}</p>
  <button @click='reverse'>反転</button>
</div>
```

```js:js
new Vue({
  el: '#app',
  data: {
    message: 'Hello VueJS!'
  },
  methods: {
    reverse: function(){
      this.message = this.message.split('').reverse().join('');
    }
  }
})
```

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/5934c41b-c220-a5d7-51da-34a14d086ca4.gif)

# ディレクティブ
htmlタグの中に定義できるVue.js独自の属性のことです。
## v-bind
タグ属性の値をVueインスタンス内で定義した変数で表現する際に使います。

```html:html
<div id='app'>
  <a v-bind:href='url'>Qiita</a>
</div>
```

```js:js
new Vue({
  el: '#app',
  data: {
    url: 'https://qiita.com'
  }
})
```

![ezgif.com-video-to-gif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/38757f35-7ebe-8110-3cf7-beb4ad47a38c.gif)


`v-bind:`を`:`に省略することもできます。

```html:html
<div id='app'>
  <a :href='url'>Qiita</a>
</div>
```

## v-on
イベントのトリガーと呼び出す関数を定義する際に使います。

```html:html
<div id='app'>
  <p>{{ message }}</p>
  <button v-on:click='reverse'>反転</button>
</div>
```

```js:js
new Vue({
  el: '#app',
  data: {
    message: 'Hello VueJS!'
  },
  methods: {
    reverse: function(){
      this.message = this.message.split('').reverse().join('');
    }
  }
})
```

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/5934c41b-c220-a5d7-51da-34a14d086ca4.gif)

`v-on:`を`@`に省略することもできます。

```html:html
<div id='app'>
  <p>{{ message }}</p>
  <button @click='reverse'>反転</button>
</div>
```

## v-model
双方向バインディング（「入力フォーム⇆Vue変数」の同期）を実現する際に使います。

```html:html
<div id='app'>
  <input type='text' v-model='message'>
  <p>{{ message }}</p>
</div>
```

```js:js
new Vue({
  el: '#app',
  data: {
    message: 'Hello VueJS!'
  }
})
```

![ezgif.com-video-to-gif (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/f8479e2d-ad28-6793-bcc6-54cb42fe6d57.gif)


## v-if
条件に応じて表示させるhtml要素を動的に変更する際に使用します。

```html:html
<div id="app">
  <button @click="countUp">ボタン</button>
  <p>{{ count }}</p>
  <p v-if="isMultipleOf4">4の倍数</p>
  <p v-else-if="isMultipleOf2">偶数</p>
  <p v-else>奇数</p>
</div>
```

```js:js
new Vue({
  el: "#app",
  data: {
    count: 0
  },
  computed: {
    isMultipleOf4: function(){
      return this.count%4==0;
    },
    isMultipleOf2: function(){
      return this.count%2==0;
    }
  },
  methods: {
    countUp: function(){
      this.count += 1;
    }
  }
})
```

![ezgif.com-video-to-gif (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/bb029a62-6fd5-9ea8-1935-2cfac39b1f04.gif)


## v-for
配列やオブジェクトの中身を反復表示させる際に使用します。

```html:html
<div id="app">
  <ul>
    <li v-for="fruit in fruits">{{ fruit }}</li>
  </ul>
</div>
```

```js:js
new Vue({
  el: "#app",
  data: {
    fruits: ['りんご','バナナ','ぶどう']
  }
})
```

<img width="69" alt="スクリーンショット 2019-08-25 19.21.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/e068af24-fb1b-e29e-ed10-fff8f3b093ab.png">

# コンポーネント
コンポーネントとは再利用可能なVueインスタンス要素です。
複数のコンポーネントを作成して、それを部品のように組み立てることで1つのWebページを作ることができます。

## js側の書き方
コンポーネントの要素をオブジェクトで書きます（`component`変数の部分）。
書き方はVueインスタンス内での定義方法とほぼ同一です。
※data部のみ、Vueインスタンスが生成されるときの初期変数を関数で返してあげるようにします。

Vueインスタンスでコンポーネントを利用可能にするには二通りの書き方があります。
一つは`Vue.component([コンポーネント名],[コンポーネント要素])`で全てのVueインスタンスで有効にする方法。
もう一つはVueインスタンス内のcomponents部に記載することで、特定のVueインスタンスで有効にする方法です。
どちらでも構いませんが、個人的には後者の方がどのVueインスタンスでどのコンポーネントが使用されているか分かりやすくて良いと思います。

```js:js
var component = {
　data: function(){
　　　return {
　　　　　count: 0
　　　}
  },
  template: "<p>{{count}}<button @click='increment'>+1</button></p>",
  methods: {
  	increment: function(){
    	this.count += 1;
    }
  }
}

//方法１
Vue.component("sample-component",component)
new Vue({
  el: "#app",
})

//方法２
new Vue({
  el: "#app",
  components: {
  	"sample-component": component
  }
})
```

## html側での書き方
html内で先ほど指定したコンポーネント名でタグを書くだけで、その部分が丸っとコンポーネントに置きかわります。

```html:html
<div id="app">
  <sample-component></sample-component>
</div>
```

![ezgif.com-video-to-gif (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/5960fd7b-5e8d-0cdc-76a8-8c088f499375.gif)

再利用可能なので、このように複数配置することもできます。

```html:html
<div id="app">
  <sample-component></sample-component>
  <hr>
  <sample-component></sample-component>
  <hr>
  <sample-component></sample-component>
</div>
```

<img width="143" alt="スクリーンショット 2019-08-30 9.43.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/b66ea9a2-7f06-7dd7-4249-70683e6dc650.png">