Vue.jsの基礎を学ぶ

#Vue.jsの読み込み方法

一般的にはCDN(content delivery network)を利用して読み込むことが多い。

jsDeliverというオープンソースのCDNがあるのでそれを利用する。

vue.jsの公式でインストールと検索するとscriptタグが出てくるので、それをbodyタグの末尾に記載する。

```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
```

その際にバージョンを固定してあげるのがおすすめ。バージョンを上げる際も動作確認してから上げること。

##開発バージョンと本番バージョン

開発バージョンは警告出力とデバッグモードがある代わりにスピードが遅く、本番バージョンは警告とデバッグができないがスピードが速いという特徴がある。用途によって使い分けるべし。


#Vueインスタンスの作成

```js
var app = new Vue({

})
```

これが基本。これで空のVueインスタンスが作成されたことになる。


#データバインディング

データと描画を同期する仕組み。

ex)inputタグの値を変えると表示されるmessageの値が変わるなど。



#オプションを書いてみる

vueではオプションをel: '#app'のようにハッシュ形式で書いていく。

例えば

```html
<div id="app">
  
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
var app = new Vue({
  //options
  el: '#app'
})
```

このような場合、vueのオプションを適用させる要素がappというidを持つタグであるということを指定している。


#実際にデータバインディングの仕組みを作る/Hello Vue.js!の表示

```js
var app = new Vue({
  //options
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
```
このようにアプリで使うプロパティはdata:の中にハッシュ形式で書いていく。
今回作ったmessageというプロパティをview側で読み込むことでデータバインディングを行うことができる。


読み込む際は

```html
<div id="app">
  <p>
    {{ message }}
  </p>
</div>
```
このようにプロパティを{{}}で囲んであげる。

これをマスタッシュ構文。口髭構文とも呼ぶ。{{が口髭に見えるから。

注意として、プロパティを読み込むことができるのはあくまでもルートテンプレートの中だけである。

#更にオプションを足してみる/配列

```html
<div id="app">
  <p>
    {{ message }}
  </p>
  <p>
    {{ count }}
  </p>
  <p>
    {{ user.prefecture }}
  </p>
  <p>
    {{ colors[1] }}
  </p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```


```js
var app = new Vue({
  //options
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    count: 10,
    user: {
      lastName: 'Yokota',
      firstName: 'Daiki',
      prefecture: 'Tokyo'
    },
    colors: ['Red', 'Green', 'Blue']
  }
})
```

このように、Railsのuser.nameやRubyのcolors[1]のような感じでVueでもコードを書くことができる。


#ディレクティブとは？

v-で始まる特別な属性のこと。

v-bind
v-if
v-for
など。

##v-bind

属性のデータバインディングv-bindについて学ぼう。

マスタッシュ構文はテキスト内での使用しかできず、属性に指定することができない。

ここで、v-bindというディレクティブを使用する

```html
<div id="app">
  <input type="text" v-bind:value="message" />
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
var app = new Vue({
  //options
  el: '#app',
  data: {
   message: 'Hello Vue.js!'
  }
})
```

このようにすることで属性にプロパティの値を指定することができる。


##v-if

要素の表示、非表示を切り替えるときなどに使う。

```html
<div id="app">
  <p v-if="toggle">
    Hello
  </p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
var app = new Vue({
  //options
  el: '#app',
  data: {
    toggle: true
  }
})
```

このように書くことで、trueのときは値を表示、falseのときは非表示にすることができる。


##v-show

要素の表示、非表示を切り替える
こちらはcssのdisplayプロパティをon/offすることで表示を切り替えることができる。

```html
<div id="app">
  <p v-show="toggle">
    Hello
  </p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
var app = new Vue({
  //options
  el: '#app',
  data: {
    toggle: true
  }
})
```

この場合、v-ifと違ってドムツリーの中のpタグが消えるわけでは無い。
v-ifはドムレベルで削除される。

要素を頻繁に切り替える場合、v-showにした方が低コストらしい。

##v-for
オブジェクトの繰り返しに使う

配列の要素を一つずつ表示したい時などに使う。

```html
<div id="app">
  <ol>
    <li v-for="color in colors">{{ color }}</li>
  </ol>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
var app = new Vue({
  //options
  el: '#app',
  data: {
    colors: ['Red', 'Green', 'Blue']
  }
})
```

このように書く。
注目すべきは、liタグに書いてある
v-for="color in colors"である。

colorとcolorsの名前は任意だが、配列のプロパティを複数形、マスタッシュ構文の中に書く値を単数形にしておくと分かりやすい。


##v-for②/userオブジェクトのプロパティを表示してみる

v-forの使い方として、keyを指定することができる

```html
<div id="app">
  <ul>
    <li v-for="value in user">{{ value }}</li>
  </ul>
  <hr>
  <ul>
    <li v-for="(value, key) in user">
      {{ key }}: {{ value }}
    </li>
  </ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
var app = new Vue({
  //options
  el: '#app',
  data: {
    user: {
      firstName: 'Daiki',
      lastName: 'Yokota',
      age: 24
    }
  }
})
```

このようにkeyとvalueを使って書くことで

firstName: Daiki

と表示することができる。


##v-on

ボタンをクリックすると現在時刻が表示されるシステムを作ろう

```html
<div id="app">
  <button v-on:click="onclick">
    Click!
  </button>
  <p>
    {{ now }}
  </p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
var app = new Vue({
  //options
  el: '#app',
  data: {
    now: ''
  },
  methods: {
    onclick: function() {
      this.now = new Date().toLocaleString();
    }
  }
})
```

v-on:click=""はボタンがクリックされた時に〜〜の処理をjs側で行いますよーって定義している。

htmlのonclickとはボタンが押された時にjs側で呼び出されるメソッド名にあたる。

js側では、methodsオプションを追加し、
onclick:以下に処理を書いていく。

自身のnowというプロパティにアクセスする際はthis.nowという風に書く。

##v-model/双方向データバインディング

双方向バインディングとは、

dataオブジェクトの値変更→テンプレートの値変更

と、

テンプレートの値変更→dataオブジェクトの値変更

どちらも行うことができる。


```html
<div id="app">
  <p>
   <input type="text" v-model="message">
  </p>
  <p>
   <input type="text" v-model="message">
  </p>
  <pre>{{ $data }}</pre>
 
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
var app = new Vue({
  //options
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
```

v-modelを使うことで双方向バインディングを実現している。

ポイントは、
1.1つ目のinputの値が変わる
2.messageプロパティの値が変わる(双方向バインディング)
3.2つ目のinputの値が変わる

という順番で動作が起こっていることを覚えておこう。


#コンポーネント

コンポーネントとは、ページを構成するUI部品。
よく使う機能をコンポーネント化し、再利用性を高めることができる。

##Hello!と表示するUIパーツを作成して使い回す

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

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```

```js
Vue.component('hello-component', {
  template: '<p>Hello</p>'
})
var app = new Vue({
  //options
  el: '#app',
})
```

構文は以下である。

```js
Vue.component('component名', {
  template: '表示したい要素ex)<p>hello</p>
})
```

これで、view側で、<component名></component名>とすることでjs側で指定した要素を表示することができる。


#ToDoアプリを作る


最終的なコード

```html
<div id="app">
  <h2>TODO List</h2>
  <form v-on:submit.prevent>
    <input type="text" v-model="newItem">
    <button v-on:click="addItem">
      Add
    </button>
  </form>
  <ul>
    <li v-for="(todo, index) in todos">
    　<input type="checkbox" v-model="todo.isDone">
      <span v-bind:class="{ done: todo.isDone }">
        {{ todo.item }}
      </span>
      <button v-on:click="deleteItem(index)">Delete</button>
    </li>
  </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16"></script>
```


```css
#app ul {
  list-style: none;
}

#app li > span.done {
  text-decoration: line-through;
}
```


```js
var app = new Vue({
  //options
  el: '#app',
  data: {
  	newItem: '',
    todos: []
  },
  methods: {
    addItem: function(event) {
      //タスクが未入力の場合は配列にタスクを追加しない
      if(this.newItem == '') return;
      var todo = {
        item: this.newItem,
        //タスクの完了・未完了
        isDone: false
      }
      //配列にタスクを追加する
      this.todos.push(todo)
      //入力欄を空欄にする
      this.newItem = ''
    },
    deleteItem: function(index) {
      //タスクを削除するspliceメソッド
      this.todos.splice(index, 1)
    }
  }
})
```

注意点はindex。
これは、配列なのでkeyにはindex番号は入るということ。

spliceメソッドは第一引数に削除する要素のindex番号、2つ目に削除する長さを指定することができる。