2018.01.24

Vue.js入門 (3) クラスとスタイル


今回はVue.jsのテンプレート機能のうち、見た目やスタイルに関連する機能を紹介します。

🌟 Notice 🌟
記事中のCodePenは右上の "Edit on CodePen" からコード編集画面に遷移できます。
ぜひ手元でコードを変えて結果を確かめてみてください。理解が早まると思います。

前提

マシーン ブラウザ Vue
macOS Sierra 10.12 Firefox Quantum ver. 2.5

HTMLクラス

See the Pen Vue.js HTML class by Masahiro Harada (@MasahiroHarada) on CodePen.

まずはクラス属性を操作する方法を紹介します。データの状態に応じてスタイルと連動したクラスを付け替えるというのはよくある処理ですよね。

上のサンプルをご覧ください。まず他のHTML属性と同様に属性名の先頭にコロンを付けます( :class="{***}")。クラス属性の場合はオブジェクトを値に指定します。引用符の中はJavaScriptオブジェクトとして評価されるわけです。

:class="{ 'text-error': message.error }"

属性の値として指定したオブジェクトのキー( 'text-error' )がクラス名です。そして、オブジェクトの値( message.error )は真偽値として評価されます。値が真と評価された場合はキーのクラス名がタグに追加されます。逆に偽と評価された場合はキーのクラス名がタグから削除されます。

上の例では message.errortrue の場合はクラス text-error<p> に付与されます。

また、すでに普通にクラス属性が指定されている場合は、最終的なクラス属性の値はマージされます。

マニュアル

他にもオブジェクトではなく配列を指定する方法もあるようです。より詳しくはこちらを参照してください。
クラスとスタイルのバインディング — Vue.js

style属性

See the Pen Vue.js styles by Masahiro Harada (@MasahiroHarada) on CodePen.

次にstyle属性を操作する方法を紹介します。

インラインのstyle属性を操作する機会はあまりないかもしれませんね。(インラインのstyleをアンチパターンと教わっている方も多いのではないでしょうか。)

それはそうと、上の例ではBootstrapを利用してプログレスバーを作成しています。<div class="progress-bar">width スタイルに応じてバーに色がついていきます。Vue側の progress の値を変えてみてください。色のつく領域が変化するはずです。

<div class="progress-bar" :style="{width: '60%'}">

クラス属性と同様に、スタイル属性も値としてJavaScriptオブジェクトを取ります。引用符の中はJavaScriptオブジェクトとして評価されます。オブジェクトの意味するところは分かりやすいかと思います。オブジェクトのキーがCSSのプロパティにあたり、オブジェクトの値がCSSの値となります。

上の例ではVue側の progress 値の変更がテンプレート側にも自動的に反映されます。その結果、width スタイルの値が変化します。

マニュアル

より詳しくはこちらを参照してください。
クラスとスタイルのバインディング — Vue.js

v-cloak

v-cloak も見た目に関わる使われ方をするので本記事に含めました。

まず、以下のようなHTMLファイルがあるとします。

<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
</head>
<body>
  <div id="app">
    <h1>{{ message }}</h1>
  </div>

  <script src="https://unpkg.com/vue"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello world'
      }
    })
  </script>
</body>
</html>

このHTMLファイルを開いていただくと、一瞬、このような表示にならないでしょうか。

スクリーンショット

なぜこのような表示になるかというと、HTMLとしてレンダリングされてからVueインスタンスが生成されてデータ部分が書き換わるまでに、一瞬とはいえタイムラグが存在するからです。

このちょっと格好わるい現象を防ぐために、v-cloak 属性を用います。

具体的には以下のようにファイルを変更します。

<!DOCTYPE html>
<html>
<head>
  <title>Welcome to Vue</title>
  <style>
    [v-cloak] {
      display: none;
    }
  </style>
</head>
<body>
  <div id="app" v-cloak>
    <h1>{{ message }}</h1>
  </div>

  <script src="https://unpkg.com/vue"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello world'
      }
    })
  </script>
</body>
</html>

まず <div id="app">v-cloak 属性を追加しています。さらにv-cloak 属性を持つ要素に対して display: none; を指定しています。

この v-cloak 属性は、Vueインスタンスの生成が完了するとVue自身によって削除される特徴を持ちます。Vueインスタンスの生成完了前は <div id="app" v-cloak>display: none; が適用されるので非表示です。Vueインスタンスの準備ができたあとは v-cloak 属性が削除されるので、display: none; が適用されなくなります。そのころにはデータ部分の書き換えが済んでいるので、二重中カッコが表示されるタイミングがなくなるというわけです。


以上、Vue.jsのテンプレート機能のうち、見た目やスタイルに関連する機能を紹介しました。

関連記事

Vue.js入門(全7回)