v-if

v-ifの使い方-Vue.js

Vue.js Article

ここでは、v-ifディレクティブの使い方をサンプルコードを参考に解説していきます。

v-ifの基本的な使い方

扱っているデータの状態に応じて条件分岐し、表示を切り替えたいとき、v-ifディレクティブを使うことができます。 記述の形式は以下の通りです。

Vue.js
v-if="変数"  v-if="条件式"

対象のブロックは、変数や条件式が真のときのみ描画されます。 実際に動くコードとその結果を見てみましょう。

Vue.js
<div id="app">
  <div v-if="flag">描画される</div>
  <div v-if="!flag">描画されない</div>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      flag: true
    }
  })
</script>
結果
<div id="app">
  <div>描画される</div>
  <!---->
</div>

変数が真ではない場合には上記のようにコメントアウトされます。

v-else

else文の役割をするv-elseディレクティブも存在します。 v-ifの後に記述することができ、v-ifが条件を満たさなかった場合に表示されます。

Vue.js
<div id="app">
  <div v-if="flag">描画される</div>
  <div v-else>v-else1</div>
  <div v-if="flag2">描画されない</div>
  <div v-else>v-else2</div>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      flag: true,
      flag2: false
    }
  })
</script>
結果
<div id="app">
  <div>描画される</div>
  <div>v-else2</div>
</div>

v-elseがある場合には描画されなかった要素のコメントアウトの表示もなくなります。

v-else-if

複数の条件を同時に使いたい場合にはv-else-ifディレクティブが使えます。 こちらもv-ifの後に記述することができ、直前のv-ifv-else-ifが条件を満たさず、指定した条件を満たす場合に表示されます。

Vue.js
<div id="app">
  <div v-if="flag > 0">flag は 正</div>
  <div v-else-if="flag < 0">flag は 負</div>
  <div v-else-if="flag === 0">flag は 0</div>
  <div v-else>flag は 数ではない</div>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      flag: 'apple'
    } 
  }) 
</script>
結果
<div id="app">
  <div>flag は 数 ではない</div>
</div>

こちらも描画されなかった要素のコメントアウトの表示はなくなります。

templateタグ

複数を同時に切り替えたいとき、それぞれにv-ifv-else-ifv-elseを付けるのは面倒です。

かといってわざわざ新しく要素でまとめては他との階層が分かれてしまったり、ulolのようにまとめられない(liのみしか入れられない)といった問題が発生します。

そんなときにはtemplateタグを使って解決することができます。

Vue.js
<div id="app">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <template v-if="flag">
      <li>4</li>
      <li>5</li>
      <li>6</li>
    </template>
    <template v-else>
      <li>7</li>
      <li>8</li>
      <li>9</li>
    </template>
  </ul>
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      flag: false
    } 
  }) 
</script>
結果
<div id="app">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
  </ul>
</div>

上記のようにtemplateタグは描画されません。 また、こちらも描画されなかった要素のコメントアウトの表示はなくなります。

ちなみに、同じような働きをするv-showtemplateタグでは使えないので注意が必要です。

v-else, v-else-ifとkey

Vue は要素を可能な限り効率的に描画しようして、要素を再利用することがよくあるそうです。これがv-ifなどでも起こるのですが、これらには以下のような注意する点があります。

  • 同じ要素の属性の状態が残る
  • transitionうまく動作しない

一つ目の例が以下です。

Vue.js
<div id="app">
  <template v-if="type">
    <label>type1</label>
    <input placeholder="type1">
  </template>
  <template v-else>
    <label>type2</label>
    <input placeholder="type2">
  </template>
  <input type="button" @click="switchType()" value="Switch!">
</div>
<script>
  var app = new Vue({
    el: "#app",
    data: {
      type: true
    },
    methods: {
      switchType(){
        this.type = !this.type
      }
    }
  }) 
</script>

Switchボタンを押すとlabelinputが切り替わりますが、値を入力した状態で切り替えても値は保持されたままとなっています。もし値を保持したいのであれば問題ありませんが、そうでない場合には困った動作です。

これを解決する方法がkey属性を与えてあげる方法です。ユニークな値を key 属性を追加することでVueがそのkeyを追跡し再利用されなくなります。

key属性についてはこちら

v-ifとv-for

v-forv-ifを同じタグに対して用いることは推奨されていません。 というのも、v-forの方がv-ifよりも評価される優先度が高いために、パフォーマンスの低下などのデメリットが生じるからです。

対策としては、以下のような方法があります。

  • 配列の要素に対する場合、配列に対して算出プロパティを用いてフィルタリングを掛ける。
  • 配列全体に対する場合、親要素(ul , ol)に対してv-ifを用いる。

公式のスタイルガイドにて詳しく解説がありますのでそちらを参照してください。

スタイルガイド

まとめ

今回はv-ifの基本的な使い方を解説しました。 同様に条件によって表示を切り替えるv-showディレクティブというものがあるので、別の記事で解説したいと思います。