Vue初心者のメモ

[その２](https://qiita.com/hysk/items/48c242025123e1d0941b)
# コンポーネントに値を渡す
## props

```
<ChildComponent hoge="value"></ChildComponent>
```

```
export default {
    props: [
        'hoge'
    ]
}
```
# ディレクティブ
ディレクティブはv-から始まる特別な属性。その属性値には単一のJS式を期待する。（ただしv-forは例外）
ディレクティブの仕事は、属性値の式が変化した時に、リアクティブに副作用をDOMに適用すること。

### 引数
引数を取るディレクティブがある。ディレクティブ名の後にコロンで表記する。

```
<span v-bind:id="hogeId">HOGEHOGE</span>

<button v-on:click="registerUser">Register</button>
```

### 動的引数
角括弧で囲むことで、単一のJS式をディレクティブ引数に使うことができる（Ver2.6.0から）

```
<button v-on:[eventname]="registerUser">Register</button>
```
※動的引数の制約
動的引数の式は最終的にNULLかStringに評価されることが期待されている。それ以外の場合は警告となる。
スペースや引用符のような一部の文字は、HTMLの属性名として不正な文字のため使えない。（構文エラーとなる）
in-DOMテンプレートを使う場合、ブラウザが強制的に属性名を小文字に変換するため、キー名を大文字にするのは避けるべき

### 修飾子(Modifier)
ドットで表記された特別な接尾語。
ディレクティブが特別な方法で束縛されるべき、ということを示す。

```
<form v-on:submit.prevent="onSubmit"> ... </form>
```


## v-bind

```
```

## v-if

## v-for

## v-on

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



# 省略記法
v-bindとv-onは頻繁に使うため省略記法が用意されている。
### v-bind

```
<a v-bind:href="targetUrl"> ... </a>
<a :href="targetUrl"> ... </a>
<a :[attr]="targetUrl"> ... </a>
```

### v-on

```
<a v-on:click="doSomething"> ... </a>
<a @click="doSomething"> ... </a>
<a @[eventName]="doSomething"> ... </a>

```

# Vueインスタンス
## プロパティ
自身のdataオブジェクトの全てのプロパティをリアクティブシステムに追加する
-> プロパティの値が変更されるとビューが反応し、新しい値に一致するように更新される

dataのプロパティはVueインスタンスが生成された時に存在していた場合のみリアクティブ
-> 後から新しいプロパティを追加しても、その変更はビューの更新を引き起こさない

## ライフサイクルフック
created, mounted, updated, destoyedなど
全てのライフサイクルフックにおいて、thisがVueインスタンスを指す形で実行される
※インスタンスプロパティやコールバックでアロー関数を使用しないこと！
-> アロー関数はthisを持たないため（親スコープまで探索される） 

## ライフサイクルダイアグラム
[公式ドキュメントの図を参照](https://jp.vuejs.org/v2/guide/instance.html#%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%83%80%E3%82%A4%E3%82%A2%E3%82%B0%E3%83%A9%E3%83%A0)

#  テンプレート構文
※直接render関数で書くことも可能
## テキスト
Mustache （二重中括弧)

```
<span>Hello, {{ message }}</span>
```

## 生のHTML
v-htmlディレクティブ

```
<span v-html="rawHtml">Hello, Everyone!</span>
```

※動的にHTMLを描画する際にはXSSに要注意！！
## 属性
v-bindディレクティブ
※属性にMustacheは使えない

```
<span v-bind:id="targetId">Hot Coffee.<span>
```
※真偽値属性の場合は少し動きが異なるので注意

## JavaScript式の使用
全てのデータバインディング内でJS式の使用が可能！

```
{{ number + 1 }}

{{ ok ? 'Yes' : 'No' }}

{{ csvString.split(',').join('&') }}

<div v-bind:id="'list_' + key">hogehoge</div>
```

ただし単一の式だけが評価可能。以下は動作しない。

```
// これは式ではなく文なのでNG
{{ var a = 1 }}

// フロー制御もNG →三項演算子なら動く
{{ if (flg) { return 'Happy!' } }}
```

# 算出プロパティ
テンプレート内に複雑な式を書くのは適切ではない。
→複雑なロジックには算出プロパティを使うとよい。

```
<div id="sample">
  <p>Original: {{ message }}</p>
  <p>Computed: {{ reversedMessage }}</p>
</div>
```
```
var vm = new Vue({
  el: #sample,
  data: {
    message: 'I am a perfect human.'
  },
  computed: {
    reversedMessage: function () {
      return this.message.split(' ').reverse().join(' ')
    }
  }
})
```
→getter関数として作用する

#### メソッドとの違い
メソッドを使っても同じ結果を得ることができるが、下記の違いがある。
算出プロパティ→値がキャッシュされ、プロパティが変化した時だけ再計算される
メソッド→毎回計算される

#### 監視プロパティ（watched property）

```
<div id="demo">{{ fullName }}</div>
```
```
var vm = new Vue({
  el: #demo,
  data: {
    firstName: 'Takamori',
    lastName: 'Saigo',
    fullName: 'Saigo Takamori'
  },
  watch: {
    firstName: function (val) {
      this.fullName = this.lastName + ' ' + val
    },
    lastName: function (val) {
      this.fullName = val + ' ' + this.firstName
    }
  }
})
```
→冗長になってしまうので、算出プロパティの方がよさげ。

#### 算出setter関数
算出プロパティはデフォルトではｇｅｔｔｅｒのみだが、必要に応じてｓｅｔｔｅｒも使える

```
// ...
  computed: {
    fullName: {
      get: function() {
        return this.firstName + ' ' + this.lastName
      },
      set: function(newVal) {
        var names = newVal.split(' ')
        this.firstName = names[0]
        this.lastName = names[length.names - 1]
      }
    }
  }
// ...
```

# ウォッチャ
多くの場合は算出プロパティが最適だが、データの変化に応じて非同期処理やコストの高い処理を行う場合はウォッチャが便利。
[詳細は公式ドキュメントを参照](https://jp.vuejs.org/v2/guide/computed.html#%E3%82%A6%E3%82%A9%E3%83%83%E3%83%81%E3%83%A3)

# クラスとスタイルのバインディング
v-bindがclassやstyleと一緒に使われる時に特別な拡張機能が提供される。
→式が文字列だけでなく、オブジェクトと配列を返すことができる。
## クラスのバインディング
#### オブジェクト構文

```
<div v-bind:class="{ active: isActive}"> ... </div>
```
→activeクラスの有無がisActiveの真偽性によって決まる
オブジェクトは複数のフィールドを持つことも可能。
プレーンなclassと共存することも可能。
オブジェクトはインラインでなく、外部で定義することも可能。

#### 配列構文

```
<div v-bind:class="[activeClass, errorClass]"> ... </div>
```
```
// ...
  data: {
    activeClass: 'active',
    errorClass: 'error-text'
  }
// ...
```
→配列を渡してクラスのリストを適用可能。

```
<div v-bind:class="[{ active: isActive }, errorClass]"> ... </div>
```
→配列構文の中にオブジェクト構文を使うことも可能
```

#### コンポーネントにおける挙動
カスタムコンポーネントにおいてclass属性を使用するとき、これらのクラスはroot要素に追加される。
この要素上に存在するクラスは上書きされない。
コンポーネントで定義されたクラス

```
Vue.component('my-component', {
  template: '<p class="already base"> ... </p>'
})
```

呼び出し時にクラスを指定

```
<my-component class="new top"></my-component>
```

描画されるHTML

```
<p class="already base new top"> ... </p>
```

## インラインスタイルのバインディング
#### オブジェクト構文
```
<div v-bind:style="{ color: themeColor, fontSize: normalFontSize }">inline sample</div>
<div v-vind:style="styleObject">object sample</div>
```
```
data: {
  themaColor: #ff5531,
  normalFontSize: 14,
  styleObject: {
    color: 'blue',
    fontSize: 19
  }
}
```

#### 配列構文
複数のスタイルオブジェクトを適用することができる

```
<div v-bind:style="[baseStyle, specialStyle]">array sample</div>
```

#### 自動プリフィックス
ベンダー接頭辞が要求されるスタイルの場合、Vueが自動的に検出して追加する

# 条件付きレンダリング
## v-if
ディレクティブの式が真を返す時だけブロックが表示される。
elseブロックを追加することも可能。

```
<h1 v-if="flgHit">Hitted!</h1>
<h1 v-else>Oh!Missed</h1>
```

#### templateでの条件グループ
複数要素に条件を適用したい場合、<template>要素でグループ化できる。

```
<template v-if="member">
  <div>Your name</div>
  <div>hogehoge</div>
</template>
```
→最終的に<template>要素は描画されない。

#### v-else, v-else-if
v-else, v-else-ifも使用可能。

## v-show

```
<div v-show="ok">All right</div>
```

表示の有無を切り替えることができる。
CSSのdisplayプロパティで切り替えられており、DOMは常に維持されている。

## v-ifとv-show
v-if: 切り替えコストが高い
v-show: 初期表示コストが高い

## v-ifとv-for
v-ifとv-showを同時に使用することは推奨されない。

# リストレンダリング
## v-for

```
<ul id="example">
  <li v-for="item in items">{{ item.message }}</li>
</ul>
```
```
var example1 = new Vue({
  el: '#example',
  data: {
    items: [
      { message: 'hello' },
      { message: 'everyone' },
      { message: 'good bye' }
    ]
  }
})
```

v-forブロック内では、親スコープのプロパティへの完全なアクセス権を持つ
配列のインデックスを2つ目の引数としてサポートしている

```
<ul id="example2">
  <li v-for="(item, index) in items">
    {{ parentValue }} - {{ index }} - {{ item.message }}
  </li>
</ul>
```
```
var example1 = new Vue({
  el: '#example',
  data: {
    parentValue: 'This is Parent',
    items: [
      { message: 'hello' },
      { message: 'everyone' },
      { message: 'good bye' }
    ]
  }
})
```

#### オブジェクトのv-for
オブジェクトのプロパティもv-forで反復処理ができる。
2つ目の引数でプロパティのキーが取得できる。
3つ目の引数でインデックスが取得できる。

```
<div v-for="(value, key, index) in object">
  {{ index }} - {{ key }} : {{ value }}
</div>
```

### フィルタ、ソートされた結果の表示
算出プロパティ、もしくはメソッドを使って実現可能

```
<li v-for="n in evenNumbers">{{ n }}</li>

<li v-for="p in even(numbers)">{{ p }}</li>
```
```
data: {
  numbers: [1, 2, 3, 4, 5, 6]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
},
method: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}
```

#### templateでのv-for
複数の要素のブロックを表示するためにtemplateブロックを使用可能

```
<template v-for="(item, index) in items">
  <div>{{ index }}</div>
  <span>{{ item.message }}</span>
</template>
```

[その他はドキュメントを参照](https://jp.vuejs.org/v2/guide/list.html#%E7%8A%B6%E6%85%8B%E3%81%AE%E7%B6%AD%E6%8C%81)

# イベントハンドリング
## イベントの購読
v-onディレクティブによって、イベントの購読、イベント発火時のjsの実行が可能。
イベントハンドラのロジックは複雑になりがちなので、v-onはメソッド名を指定することが可能。

```
<div id='example'>
  <button v-on:click="someAction">Push</button>
</div>
```

$event変数を使うことで、メソッドにDOMイベントを渡すことも可能

```
<button v-on:click="someAction('customParam', $event)">Register</button>
```

#### イベント修飾子
* .stop
* .prevent
* .capture
* .self
* .once
* .passive

[詳細はドキュメントを参照](https://jp.vuejs.org/v2/guide/events.html#%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E4%BF%AE%E9%A3%BE%E5%AD%90)

#### キー修飾子
[ドキュメント参照](https://jp.vuejs.org/v2/guide/events.html#%E3%82%AD%E3%83%BC%E4%BF%AE%E9%A3%BE%E5%AD%90)

# フォーム入力バインディング
formの要素に双方向データバインディングを作成するためのディレクティブ。
データ更新のための基本構文のシンタックスシュガー。
要素によって異なるプロパティとイベントを持つ

|要素|プロパティ|イベント|
|:-----------|:-------------|:-----|
|テキスト、複数行テキスト|value|input|
|チェックボックス、ラジオボタン|checked|change|
|選択フィールド|value|change|

#### 修飾子
.lazy
.number
.trim