[Vue.js] v-if と v-show の違い、使い分けのポイント
(この記事では、Vue.js v2.5.13 で動作確認をしました。)
Vue.jsの条件付きレンダリング用ディレクティブ v-if と v-show について、大まかな違いと使い分けについて書きたいと思います。
公式ドキュメントの v-if vs v-showを読んでもいまいちピンと来なかった方に読んでいただければ幸いです。
v-if と v-show の違い
使ってみる
使用例を示すため、JSFiddleを用意しましたので、ご覧ください。
また、Developer Toolsをご用意ください。(Chrome, FireFox, EdgeであればF12キーで開けます)
サンプルを軽くご説明すると、テンプレートがpタグ1個のみのコンポーネントAとBがあり、
それぞれv-if, v-showディレクティブで表示/非表示を切り替えようとしています。
ルートオブジェクトのdataには表示/非表示を表す2つのBoolean変数 toggleA, toggleB を用意しており,
コンポーネントAの埋め込みには v-if ディレクティブを(v-if="toggleA")
コンポーネントBの埋め込みには v-show ディレクティブを(v-show="toggleB")を付加しています。
toggleA,toggleBともに、対応するボタンA,Bをクリックすると、その真偽値が反転するようにしています。
さて、ページを開いた時点では、真偽値切替用のA,Bボタンしか表示されていないと思います。
しかしDOMツリー上ではページを開いた時点ですでにv-ifとv-showの違いが出ており、
コンポーネントAのDOMは存在しませんが、コンポーネントBのDOMは、 display:none のスタイルが適用された状態で存在しています。
これがすなわち、公式ドキュメントにある
v-if は 遅延描画 (lazy) です。 初期表示において false の場合、何もしません。条件付きブロックは、条件が最初に true になるまで描画されません。
一方で、v-show はとてもシンプルです。要素は初期条件に関わらず常に描画され、シンプルな CSS ベースの切り替えとして保存されます。
が意味するところです。
もう少し踏み込む
ここからはv-if, v-showの真偽値を繰り返し反転した際になにが起こるのかを見ていきます。
一度ページをリロードし(またはJsFiddleメニューのRUNを押す)、Developer Toolsのコンソールを見てください。
ページを開いた時点でコンポーネントB(v-show)のcreatedフックが実行されているのがわかると思います。
Bボタンを連打しv-showが false -> true -> false -> true と繰り返し変わっても、スタイルが変化するだけのため、createdフックは最初の一度しか実行されません。
反対に、Aボタンを連打するとAコンポーネント(v-if)のcreatedフックが何度も実行されることがわかるでしょう。
v-ifはtrueからfalseに切り替わったとき、DOMが消え去り、trueに切り替わり再出現した際には、dataも初期化されています。
使い分け
表示/非表示の切り替え頻度が高い、または非表示時もdataを保持する必要がある場合には v-show を
切り替え頻度が低い、または非表示時にdataを保持する必要がない場合には v-if を使うというのを基本方針にすると良いでしょう。
v-ifを使った場合のみv-elseディレクティブが使えますが、v-elseを使いたいという理由だけでv-ifを採用するのはあまりよろしくありません。