# クラスとスタイルのバインディング

データバインディングに一般に求められることの 1 つは、要素のクラスリストとインラインスタイルを操作することです。それらはどちらも属性であるため、v-bind を使って扱うことができます。最終的な文字列を式で計算するだけです。しかしながら、文字列の連結に手を出すのは煩わしく、エラーのもとです。そのため、Vue は v-bindclassstyle と一緒に使われるとき、特別な拡張機能を提供します。文字列だけではなく、式はオブジェクトまたは配列を返すことができます。

# HTML クラスのバインディング

# オブジェクト構文

:class (v-bind:class の略) にオブジェクトを渡すことでクラスを動的に切り替えることができます:

<div :class="{ active: isActive }"></div>
1

上記の構文は、active クラスの有無がデータプロパティ isActive真偽性 (opens new window)によって決まることを意味しています。

オブジェクトにさらにフィールドを持たせることで複数のクラスを切り替えることができます。加えて、:class ディレクティブはプレーンな class 属性と共存できます。つまり、次のようなテンプレートと:

<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>
1
2
3
4

次のようなデータがあったとすると:

data() {
  return {
    isActive: true,
    hasError: false
  }
}
1
2
3
4
5
6

このように描画されます:

<div class="static active"></div>
1

isActive もしくは hasError が変化するとき、クラスリストはそれに応じて更新されます。例えば、hasErrortrue になった場合、クラスリストは "static active text-danger" になります。

束縛されるオブジェクトはインラインでなくてもかまいません:

<div :class="classObject"></div>
1
data() {
  return {
    classObject: {
      active: true,
      'text-danger': false
    }
  }
}
1
2
3
4
5
6
7
8

これは同じ結果を描画します。オブジェクトを返す算出プロパティに束縛することもできます。これは一般的で強力なパターンです:

<div :class="classObject"></div>
1
data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 配列構文

:class に配列を渡してクラスのリストを適用することができます:

<div :class="[activeClass, errorClass]"></div>
1
data() {
  return {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
}
1
2
3
4
5
6

これは次のように描画されます:

<div class="active text-danger"></div>
1

リスト内のクラスを条件に応じて切り替えたい場合は、三項演算子式を使って実現することができます:

<div :class="[isActive ? activeClass : '', errorClass]"></div>
1

この場合 errorClass は常に適用されますが、activeClass クラスは isActive が真と評価されるときだけ適用されます。

しかしながら、これでは複数の条件つきクラスがあると少し冗長になってしまいます。そのため、配列構文の内部ではオブジェクト構文を使うこともできます:

<div :class="[{ active: isActive }, errorClass]"></div>
1

# コンポーネントにおいて

このセクションでは、Vue のコンポーネントの知識を前提としています。いったんスキップして後で戻ってきても構いません。

単一のルート要素を持つカスタムコンポーネントで class 属性を使用すると、それらのクラスがこの要素に追加されます。この要素の既存のクラスは上書きされません。

例えば、このコンポーネントを宣言して:

const app = Vue.createApp({})

app.component('my-component', {
  template: `<p class="foo bar">Hi!</p>`
})
1
2
3
4
5

使用するときにいくつかのクラスを追加したとします:

<div id="app">
  <my-component class="baz boo"></my-component>
</div>
1
2
3

以下の HTML が描画されます:

<p class="foo bar baz boo">Hi</p>
1

クラスバインディングに対しても同様です:

<my-component :class="{ active: isActive }"></my-component>
1

isActive が真と評価されるときは、以下の HTML が描画されます:

<p class="foo bar active">Hi</p>
1

コンポーネントに複数のルート要素がある場合、どのコンポーネントがこのクラスを受け取るかを定義する必要があります。これは $attrs コンポーネントプロパティを使って行うことができます:

<div id="app">
  <my-component class="baz"></my-component>
</div>
1
2
3
const app = Vue.createApp({})

app.component('my-component', {
  template: `
    <p :class="$attrs.class">Hi!</p>
    <span>This is a child component</span>
  `
})
1
2
3
4
5
6
7
8

コンポーネント属性の継承については、プロパティでない属性のセクションを参照してください。

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

# オブジェクト構文

:style 向けのオブジェクト構文は非常に簡単です。JavaScript オブジェクトということを除けば、ほとんど CSS のように見えます。CSS のプロパティ名には、キャメルケース (camelCase) またはケバブケース (kebab-case: クォートとともに使うことになります) のどちらでも使用することができます:

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
1
data() {
  return {
    activeColor: 'red',
    fontSize: 30
  }
}
1
2
3
4
5
6

テンプレートをクリーンにするために、直接 style オブジェクトに束縛するのは、よいアイディアです:

<div :style="styleObject"></div>
1
data() {
  return {
    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
}
1
2
3
4
5
6
7
8

ここでもまた、オブジェクト構文はしばしばオブジェクトを返す算出プロパティと併せて使用されます。

# 配列構文

:style 向けの配列構文は、同じ要素に複数のスタイルオブジェクトを適用することができます:

<div :style="[baseStyles, overridingStyles]"></div>
1

# 自動プリフィックス

:styleベンダー接頭辞 (opens new window)を要求される CSS プロパティを使用するとき、例えば、transform においては、Vue.js は自動的に適切な接頭辞を検出し、適用されるスタイルに追加します。

# 複数の値

style プロパティに複数の (接頭辞付き) 値の配列を設定できます。例えば次のようになります:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
1

これは、配列内でブラウザがサポートしている最後の値だけを描画します。この例では、flexbox の接頭されていないバージョンをサポートしているブラウザでは display: flex を描画します。

Deployed on Netlify.
最終更新日: 9/21/2020, 10:52:09 PM