Vue.jsのクラスとスタイルのバインディングを勉強する


# クラスとスタイルのバインディング
データバインディングに求めらることの１つは、html要素のクラスリストとインラインスタイルを操作することです。
クラスリストとインラインスタイルはどちらも属性なので**v-bind**を使って扱う事ができます。最終的な文字列を式で処理するだけです。
ですが、文字列連は煩わしく、バグのもとになります。そのため、Vue.jsは**v-bind**が**class**と**style**を一緒に使われるときの特別な拡張機能があります。
文字列だけでなく、式やオブジェクト、または配列を返すことができます。

## HTMLクラスのバインディング
### オブジェクト構文
**v-bind:class**にオブジェクトを渡すことでクラスを動的に切り替えることができる。

```html:html部分
<div id="example">
  <p class="plane" v-bind:class="{ colorRed: isRed, fontBold: isBold }" > 文字を変化させる</p>
</div>
```

```css:css部分
.colorRed{ color: red }
.fontBold{ font-weight: bold}
```

```javascript:javascript部分
let app = new Vue({
  el: '#example',
  data: {
    isRed: false,
    isBold: false
  }
})
```

```html:開発者モードのElement
<div id="example">
  <p class="plane"> 文字を変化させる</p>
</div>
```

```javascript:開発者モードのConsole
// classにcolorRedが追加され文字の色が赤色に変化
app.isRed = true

// classにfontBoldが追加され文字が太くなる
pp.isBold = true
```

```html:開発者モードのElement
<div id="example">
  <p class="plane colorRed fontBold"> 文字を変化させる</p>
</div>
```

上記の例ではcolorRedとfontBoldのクラスの有無がdataプロパティのisRedとisBoldの真偽値によって決まる事を意味しています 
また、通常の**class属性**と共存できます。
**class**と**v-bind:class**は共存できるということです。

束縛されるオブジェクトはインラインである必要はありません

```html:html部分
<div id="example">
  <!-- dataプロパティのclassObjectオブジェクトをバインディング -->
  <p v-bind:class="classObject" > 文字を変化させる</p>
</div>
```

```javascript:javascript部分
let app = new Vue({
  el: '#example',
  data: {
    classObject: {
      colorRed: false,
      fontBold: false
    }
  }
})
```

```javascript:開発者モードのConsole
// classにcolorRedが追加され文字の色が赤色に変化
app.classObject.colorRed = true

// classにfontBoldが追加され文字が太くなる
app.classObject.fontBold = true
```

同じ結果を描画します。

オブジェクトを返す（returnする）**算出プロパティ**に束縛することもできます。
算出プロパティを使う事でclassに対して関数を適応でます。

```html:html部分
<div id="example">
  <!-- computedプロパティのclassObjectをバインディング -->
  <p v-bind:class="classObject" > 文字を変化させる</p>
</div>
```

```css:css部分
.colorRed{ color: red }
.fontBold{ font-weight: bold}
```

```javascript:javascript部分
let app = new Vue({
  el: '#example',
  data: {
    isRed: false,
    isBold: false
  },
  computed: {
    // isRedかisBoldに変更が加わった時にオブジェクトを返すgetter関数
    classObject: function() {
      return {
        // isRedがtrueが入った時にtrueを返す
        colorRed: this.isRed === true,
        // isBoldにtrueが入った時にtrueを返す
        fontBold: this.isBold === true
      }
    }
  }
})
```

```javascript:開発者モードのConsole
// classにcolorRedが追加され文字の色が赤色に変化
app.isRed = true

// classにfontBoldが追加され文字が太くなる
pp.isBold = true
```

### 配列構文
**v-bind:class**に配列を渡してクラスを適応することができる。

```html:html部分
<div id="example">
  <p v-bind:class="[isRed, isBold]" > 文字を変化させる</p>
</div>
```

```css:css部分
.colorRed{ color: red }
.fontBold{ font-weight: bold}
```

```javascript:javascript部分
let app = new Vue({
  el: '#example',
  data: {
    isRed: 'colorRed',
    isBold: 'fontBold'
  }
})
```

```html:開発者モードのElement
<div id="example">
  <p class="colorRed fontBold"> 文字を変化させる</p>
</div>
```

配列構文は通常の配列同様に配列の中にオブジェクトを格納可能です。
よってオブジェクト構文と組み合わせて扱うことが可能です。

## インスタンスのバインディング

### オブジェクト構文
**v-bind:style**のオブジェクト構文は非常に簡単です。
javascriptオブジェクトということを除けば、ほとんどcssに似ています。
cssのプロパティ名には、[キャメルケース](https://designsupply-web.com/developmentlab/4052/)または[ケバブケース](https://designsupply-web.com/developmentlab/4052/)どちらも使用できます。

クラスのバインディングの時のようにインラインの記述も行えますが、束縛されるオブジェクトはインラインである必要がなく、テンプレートを綺麗な状態に保てる方法を紹介します。

```html:html部分
<div id="example">
  <p v-bind:style="styleObject" > 文字を変化させる</p>
</div>
```

```javascript:javascript部分
let app = new Vue({
  el: '#example',
  data: {
    styleObject: {
      color: 'red',
      // font-weight = fontWeight
      fontWeight: 'bold'
    }
  }
})
```

cssのプロパティ名**font-weight**はケバブケースですが、オブジェクトのkey名にケバブケースは使用できないためキャメルケースで記述する事ができます。

```html:開発者モードのElement
<p style="color: red; font-weight: bold;"> 文字を変化させる</p>
```

class同様オブジェクトを返す（returnする）**算出プロパティ**に束縛することもできます。
算出プロパティを使う事でstyleに対して関数を適応でます。

### 配列構文
**v-bind:style**の配列構文は、同じ要素に複数のスタイルオブジェクトをバインディングすることができます。

```html:html部分
<div id="example">
  <p v-bind:style="[styleObjectA,styleObjectB]" > 文字を変化させる</p>
</div>
```

```javascript:javascript部分
let app = new Vue({
  el: '#example',
  data: {
    styleObjectA: {
      color: 'red',
      // font-weight = fontWeight
      fontWeight: 'bold'
    },
    styleObjectB: {
      // font-size = fontSize
      fontSize: '50px'
    }
  }
})
```

```html:開発者モードのElement
<div id="example">
  <p style="color: red; font-weight: bold; font-size: 50px;"> 文字を変化させる</p>
</div>
```

## あとがき
公式リファレンスには「コンポーネントにおいて」と「自動プレフィックス」という項目がありますが、この記事では書きません。


## 参考資料
[公式リファレンス](https://jp.vuejs.org/v2/guide/class-and-style.html)