Vue.js入門 ―最速で作るシンプルなWebアプリケーション

第2回 Vue.js基礎文法最速マスター

この記事を読むのに必要な時間:およそ 5 分

条件付きレンダリング

表示・非表示を切り替えたい場合には,v-showディクレティブ,v-ifディレクィブを使います。属性値の式を評価して真とみなせる場合には要素を表示し,偽とみなせる場合には要素を非表示にします。

よくあるケースとしては,以下のようなバリデーションのエラーメッセージの表示があります。以下の例では,名前が一文字も入力されていない状態で式(!isValid)が真として評価され,エラーメッセージが表示されます。

var vm = new Vue({
  el: '#example',
  data: {
    name: '',
  },
  computed: {
    isValid: function () {
      return this.name.length > 0;
    }
  }
});
window.vm = vm;
<div id="example">
  <p>名前 {{ name }}</p>
  <p v-show="!isValid">
    名前を入力してください
  </p>
</div>

後ほどUIから入力を受けつける方法を紹介しますが,Consoleから値を変更することで,要素の表示・非表示を確かめてみましょう。開発者ツールのConsoleタブのコンテキストが「result (fiddle.jshell.net)」となっているか確認して,以下のようにnameの値を変更します。

エラーメッセージが表示されなくなることを確認できます。

vm.name = 'John';

v-if, v-showいずれも式の結果に応じて,表示・非表示を切り替えることができますが,それをどう実現しているかが異なります。

v-ifは式の結果に応じてDOM要素を追加・削除するのに対して,v-showはスタイルのdisplayプロパティの値を変更することで実現します。使い分けの基準としては,切り替えの頻度と初期表示のコストです。一般的にスタイルの操作よりもDOMの操作のほうがレンダリングのコストが高いので,頻繁に式の評価結果が変わる場合にはv-showを使うべきです。

一方,評価結果が偽から真へ一度しか変わらないようなケース,たとえば,ページ表示時にログイン状態か確認してからデータを取得して表示するような場合を想定してみましょう。この場合,初期表示時はDOM要素を生成せずレンダリングのコストを抑え,必要になったらDOM要素を生成するのが理想です。このような場合には,v-ifを使うとよいでしょう。

条件付きレンダリングのサンプルコードは,このURLから確認できます。

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

アプリケーションを開発していて,特定の条件が成立する場合に,見た目を変えたいケースがあるはずです。たとえば,先ほどの例でいえば,バリデーションエラーの場合はフォームを赤く囲んで表示したくなりませんか。このようなときに使えるのが,v-bind:class, v-bind:styleディレクティブです。

v-bind:classディレクティブは,属性値にオブジェクトを指定した場合に,値が真であるプロパティ名をclass属性値として反映します。先ほどの例のHTMLにv-bind:classディレクティブを適用してみましょう。この場合,isValidがfalseの場合はclass属性値が"error"になり,"error"というクラス名が指定されていることが確認できるはずです。

また,複数のクラス名を扱いたい場合は,オブジェクトではなくクラス名の文字列が格納された配列をv-bind:classディレクティブの属性値に指定することもできます。この場合は,配列を返す算出プロパティを用意するとよいでしょう。

<div id="example" v-bind:class="{'error': !isValid}">
  <p>名前 {{ name }}</p>
  <p v-show="!isValid">
    名前を入力してください
  </p>
</div>

v-bind:styleディレクティブでは,属性値のオブジェクトのプロパティがスタイルのプロパティと対応して,インラインスタイルとして反映されます。以下のように記述した場合,isValidがfalseの場合のstyle属性値は"border: 1px solid red;"となることが確認できるはずです。

<div id="example" v-bind:style="{'border': (isValid ? '' : '1px solid red')}">
  <p>名前 {{ name }}</p>
  <p v-show="!isValid">
    名前を入力してください
  </p>
</div>

v-if, v-showと同様にConsoleタブで,nameプロパティの値を変更して,表示が切り替わることを確認してみてください。スタイルのバインディングのサンプルコードは,このURLから確認できます。

メソッドとイベントハンドリング

v-onディレクティブを利用することで,DOMイベントをハンドリングして,JavaScriptのコードを実行することができます。

これまでの例を改良して,UIから入力を受け付けるようにしてみましょう。名前を表示するタグとエラーメッセージを表示するタグの間に以下の内容を追加します。

  <p>
    <input type="text" v-on:input="name = $event.target.value">
  </p>

v-onディレクティブの後ろにはイベント名が続きます。上の例はinputイベントをハンドリングして,入力の度にnameプロパティを変更しています。もちろん他のイベントを指定することもできます。入力の度に変更するのではなくテキストボックスがフォーカスされ,入力作業が完了したタイミングで変更をおこなう場合には,inputイベントの代わりにchangeイベントを利用します。

    <input type="text" v-on:change="name = $event.target.value">

属性値は,JavaScript式になっており,直接nameプロパティを変更しています。$eventは,Vue.jsが提供しているDOMイベントのオブジェクトへの参照です。

Mustache記法の場合と同様に,同じ式を複数の箇所に記述したり複雑な式を記述する場合には,JavaScript式ではなくメソッドを定義してそれを呼びだすこともできます。メソッドは,Vueインスタンスを生成する際のmethodsオプションで定義します。

var vm = new Vue({
  // ...
  methods: {
    updateName: function(event) {
      this.name = event.target.value;
    }
  }
  // ...
});
  <input type="text" v-on:input="updateName($event)">

もうひとつ,入力された値をサーバに送信すると仮定して,v-onディレクティブを利用してみましょう。エラーメッセージを表示する要素の下に以下の内容を追加してください。

  <p v-show="isValid">
    <button v-on:click="sendData">送信</button>
  </p>

また,methodsプロパティでsendData関数の定義を行ってください。

var vm = new Vue({
  // ...
  methods: {
    updateName: function(event) {
      this.name = event.target.value;
    },
    sendData: function() {
      alert(this.name);
    }
  }
  // ...
});

ボタンをクリックすることで,sendData関数が実行されていることがわかります。今回は,サーバのプログラムを用意していないのでalertで出力するだけですが,本来はXMLHttpRequestやFetchを利用してサーバと通信をおこないます。メソッドとイベントハンドリングのサンプルコードは,このURLで確認できます。

フォーム入力バインディング

先の例では,UIから入力を受け付けて状態を変更するためにイベントハンドリングとメソッドを利用しましたが,v-modelディレクティブを利用すればこれを簡潔に実現できます。これは双方向データバインディングを実現するディレクティブで,View(DOM)で変更があった場合にはViewModelの状態として反映します。逆にViewModelの状態の変更があった場合にはView(DOM)の値として反映します。

先ほどの例を,v-modelディレクティブで実現する場合には,inputタグを以下のように変更します。updateNameメソッドの定義は消してしまって構いません。

<input v-model="name">

どうでしょう。v-on:inputと同じ動きが実現できています。もしinputイベントではなくchangeイベントと同様の動きを実現する場合には,v-modelディレクティブの挙動を変更する修飾子(Modifier)という仕組みを利用します。今回は,lazyという修飾子を利用します。

<input v-model.lazy="name">

今回は紹介できませんでしたが,修飾子はv-onディレクティブにも存在し,DOMイベントを中断したりキー入力を制限するものがあります。v-modelの他の修飾子も併せてガイドAPIリファレンス を参照してみてください。

フォーム入力バインディングのサンプルコードは,このURLで確認できます。

まとめ

いかがでしたか。DOM APIやjQueryを利用するよりも,UIの実装がシンプル・簡潔にできると感じていただけたでしょうか。Vue.jsのテンプレートはHTMLベースで宣言的なので,独自のシンタックスを覚える必要がなく,とりかかりやすいです。直感的に読み書きを行うことができるのも特徴です。既存のプロジェクトへの導入も容易なので,ぜひ,ご自身のプロジェクトで,ちょっとしたUIの実装にVue.jsを活用してみてください。

次回は,Vue.jsのコンポーネントの機能について紹介します。お楽しみに。

著者プロフィール

喜多啓介(きたけいすけ)

1991年生まれ。LINE株式会社にて,JavaScriptを中心にクライアントサイドの実装を担当。Vue.jsの柔軟性に注目し,業務・趣味を問わず活用している。最近はウェブサイトの表示スピードやランタイムのパフォーマンス改善に関心がある。

ブログ:http://kitak.hatenablog.jp/
Twitter:@kitak

コメント

コメントの記入