Vue.js で条件つきで要素を操作してみる

フロント開発がもっと楽しくなる!Vue.js 学習メモ。v-if / v-show / 算出プロパティを使って条件によって要素や属性などの内容を切り替えます。

表示・非表示の条件を指定するには、 v-show、v-if、などのディレクティブを使用します。

2つの違いは、v-show は display:none を付けて表示上でのみ見えなくしているのに対して v-if は DOM レベルで削除します。表示・非表示を何度も切り替えるような場合は v-show を使う方がパフォーマンス的に良いようです。

v-for と v-show を使って特定の条件のデータだけ表示

以下のデータを使って、入力した数値以下の商品だけを表示するようにしたいと思います。

var vm = new Vue({
    el: '#app1',
    data: {
        price: 0,
        inputprice: 200,
        list: [{
            'name': 'とまと',
            'price': '100'
        }, {
            'name': 'れたす',
            'price': '200'
        }, {
            'name': 'きゅうり',
            'price': '300'
        }],
    }
});

v-show の書き方は以下のようになります。


<elem v-for="val in list" v-show="条件式">条件を満たしたら表示される</elem>

条件式の部分には JavaScript の if 文のカッコ内で書くような式を書きます。真偽値を返すデータを渡しても良いです。 v-if も書き方は同じです。

<ul>
<li v-for="val in list" v-show="val.price <= price">
{{ val.name }} <span v-bind:style="{color: val.price <= 200 ? 'red' : 'blue'}">{{ val.price }}円</span>
</li>
</ul>
<input v-model="inputprice" size="5"> 円以下の商品を表示
<button @click="price = inputprice">click!</button>

v-model の値を使うとリアルタイムで反映されますが、今回はボタンを押したら別のデータに代入してクリックするまではリストが反応しないようにしています。

数字をうつとそれ以下の値段の商品だけ表示されましたね(•ө•)ノ 実際には数字以外が入力され場合の例外処理とかも必要ですがリアルタイムフィルタリングとか簡単に出来る機能があったりするのでしょうか?またあとで調べます。

ちなみに、フォームバインディング用の v-model には「フォーカスが外れた時にアクティブ化する」みたいな修飾子もあるので遅延処理も可能です。

スタイルやクラスにも条件を付けたい

上の例ではついでに値段が200円以下なら赤くするようにしました。 style と class は値が複数になる事があるため v-bind でそれぞれに条件を付ける事ができます。v-bind を付けずに普通に書いている style や class があった場合はマージされた結果が表示されます。

さて、ここで同時に「X件見つかりました」や「何も見つかりませんでした」みたいな表示もしたいのですが、最終的にヒットした数値をどうやって取得したらいいのでしょうか?マニュアルを見ると算出プロパティと言うものがあります。データを取得する時に処理が出来る機能みたいなのでこれを使えば出来そうな気がします。

算出プロパティを使う

算出プロパティは自作出来るゲッター関数でなんらかの処理をした結果をデータとして返せます。上の例と違うのは v-for に渡された時点で既に条件を満たしたものだけになっているという事です。methods と同じように computed というプロパティに関数を登録します。

var vm = new Vue({
    el: '#app2',
    data: {
        price: 300,
        inputprice: 200,
        list: [{
            'name': 'とまと',
            'price': '100'
        }, {
            'name': 'れたす',
            'price': '200'
        }, {
            'name': 'きゅうり',
            'price': '300'
        }]
    },
    computed: {
        testlist: function() {
         console.log('getlist');
            var $this = this;
            return this.list.filter(function(val) {
                if (val.price <= $this.price) {
                    return true;
                }
            });
        }
    }
});

getlist という名前で簡単な算出プロパティを作ってみました。

<ul>
    <li v-for="val in getlist">
        {{ val.name }} <span v-bind:style="{color: val.price <= 200 ? 'red' : 'blue'}">{{ val.price }}円</span>
    </li>
    <li v-if="!getlist.length">
        該当する商品はありません
    </li>
</ul>
<input v-model="inputprice" size="5"> 円以下の商品を表示
<button @click="price = inputprice">click!</button> {{getlist.length}}個見つかりました

算出プロパティで先に処理をすればその結果の length を見ればヒット数がわかりますね!

でも getlist を3箇所も使ってるのでその度に関数が実行されるのかなーと不安に思って console.log を入れてみたら1回しか実行されていません。算出プロパティは元のデータが更新されるまではキャッシュされるみたいです。超便利。でも大丈夫! method さんにも得意な事があるからね!

算出プロパティは依存関係にもとづきキャッシュされるという違いがあります。

算出プロパティ vs メソッド

v-if /v-else-if / v-else で複数の条件を設定できる

v-if と組み合わせて v-else-if、v-else というようなディレクティブも使用できます。必ず条件要素の直後に置くようにして使用します。

条件分岐の方法と算出プロパティの便利さがわかりました。次はいよいよコンポーネントについて勉強したいと思います。

Edited on 2017.02.18 Created on 2017.02.15 Vue.js JavaScript Webデザイン