条件付きレンダリング
v-if
v-ifディレクティブは、要素を条件に応じて描画したい場合に使用する。
<div id="example">
<p v-if="awesome"> 条件がtrueの時に表示される </p>
</div>
let app = new Vue({
el: '#example',
data: {
awesome: false
}
})
app.awesome = true
// true
条件がtrueの時に表示される
v-else
通常のjavascript同様にv-elseでelseを記述することが可能です。
v-else要素は、v-ifまたはv-else-if要素の直後になければいけません。
それ以外の場合は認識されません。
<div id="example">
<p v-if="awesome"> 条件がtrueの時に表示される </p>
<p v-else="awesome"> 条件がfalseの時に表示される </p>
</div>
let app = new Vue({
el: '#example',
data: {
awesome: false
}
})
app.awesome = true
// true
条件がtrueの時に表示される
v-else-if
通常のjavascript同様にv-else-ifでelse ifを記述することが可能です。
v-else-if要素は、v-ifまたはv-else-if要素の直後になければいけません。
それ以外の場合は認識されません。
<div id="example">
<p v-if="awesome == 'A'"> 条件がAの時に表示される </p>
<p v-else-if="awesome == 'B'"> 条件がBの時に表示される </p>
<p v-else-if="awesome == 'C'"> 条件がCの時に表示される </p>
<p v-else="awesome"> 条件に当てはまらなった時に表示される </p>
</div>
let app = new Vue({
el: '#example',
data: {
awesome: ''
}
})
条件に当てはまらなった時に表示される
app.awesome = 'A'
// "A"
// ブラウザの表示:条件がAの時に表示される
app.awesome = 'B'
// "B"
// ブラウザの表示:条件がBの時に表示される
app.awesome = 'C'
// "C"
// ブラウザの表示:条件がCの時に表示される
app.awesome = 'D'
// "D"
// ブラウザの表示:条件に当てはまらなった時に表示される
テンプレートでのv-ifによる条件グループ
v-ifはディレクティブなので、1つの要素に付加する必要があります。
1要素よりも多くの要素を切り替えたい場合にHTML のコンテンツテンプレート(< template >)要素を使用します。
<div id="example">
<template v-if="boxflg">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
</div>
let app = new Vue({
el: '#example',
data: {
boxflg: false
}
})
app.boxflg = true
// true
Title
Paragraph 1
Paragraph 2
<div id="example">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</div>
htmlのElementにコンテンツテンプレートが含まれることはありません。
key による再利用可能な要素の制御
Vue.jsは要素を可能な限り効率的に描画しようとしますが、1からレンダリングするかわりにそれら要素を再利用することがよくあります。
Vue.jsを非常に速くするのに役立つ以外にも、これにはいくつかの便利な利点があります。
たとえば、ユーザーが複数のログインタイプを切り替えることを許可する場合は、次のようにします。
- UserNameでログイン
- Emailでログイン
上記の2つを切り替える入力画面を作ります。
<div id="example">
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
<button @click="change">ログイン方法変更</button>
</div>
正直愚直なコードな気がして最善な書き方では無い気がしますが…
let app = new Vue({
el: '#example',
data: {
loginType: 'username'
},
methods: {
change(){
if (!(this.loginType == "username")) {
this.loginType = "username"
}else{
this.loginType = "email"
}
}
}
})
上記のコードでloginTypeを切り替えても、ユーザーが既に入力したものは消去されません。
両方のテンプレートが同じ要素を使用するので、< input > は置き換えられません。
placeholderが切り替わるだけです。
この結果は望ましい結果では無いかもしれません。
この2つの要素は完全に別個のもので、再利用したく無い場合があり、要素に一意であることを示すためにkey属性を追加します。
<div id="example">
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
<button @click="change">ログイン方法変更</button>
</div>
javascriptのコードは上記の例と変更はありません。
これでログイン方法が変更ボタンが押されるたびにinputが再利用されなくなります。
v-show
条件的に要素を表示するための別のオプションです。
使用方法はv-ifとほとんど同じです。
<div id="example">
<p v-show="awesome"> 条件がtrueの時に表示される </p>
</div>
let app = new Vue({
el: '#example',
data: {
awesome: false
}
})
<div id="example">
<p style="display: none;"> 条件がtrueの時に表示される </p>
</div>
app.awesome = true
// true
条件がtrueの時に表示される
<div id="example">
<p style> 条件がtrueの時に表示される </p>
</div>
v-ifとの違いは v-sowディレクティブでは要素自体は常に描画されてDOMに維持するということです。
v-showはシンプルに要素のdisplayCSSプロパティを切り替えているだけです。
【注意】
v-showはコンテンツテンプレートをサポートしていません。
<div id="example">
<template v-show="boxflg">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
</div>
これはコンテンツテンプレートがDOMのElementsに含まれないためです。
v-if vs v-show
v-if
イベントリスナと子コンポーネント内部の条件ブロックが適切に破棄され、切り替えられると再レンダリングされるため、"リアル"な条件レンダリングです。
v-ifは遅延描画(lazy)です。
初期表示においてfalseの場合レンダリングされず、条件がtrueになったときにレンダリングされます。
v-show
要素は条件に関わらず常に描画されており、displayCSSプロパティを切り替えているだけです。
結論
シンプルかつ頻繁に切り替える必要があるのならばv-showを使用し
複雑な処理、条件が実行時から変更されることがほとんどない場合はv-ifを選ぶ
あとがき
v-ifとv-forの題目はv-ifとv-forを同時に利用する事は推奨されておらずバッドプラクティスですということです。
詳細はスタイルガイドを参照してください