7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.js の条件付きレンダリングを勉強する

Last updated at Posted at 2019-07-09

条件付きレンダリング

v-if

v-ifディレクティブは、要素を条件に応じて描画したい場合に使用する。

html部分
<div id="example">
  <p v-if="awesome"> 条件がtrueの時に表示される </p>
</div>
javascript部分
let app = new Vue({
  el: '#example',
  data: {
    awesome: false
  }
})
開発者モードのConsole
app.awesome = true
// true
ブラウザの表示
条件がtrueの時に表示される

v-else

通常のjavascript同様にv-elseでelseを記述することが可能です。
v-else要素は、v-ifまたはv-else-if要素の直後になければいけません。
それ以外の場合は認識されません。

html部分
<div id="example">
  <p v-if="awesome"> 条件がtrueの時に表示される </p>
  <p v-else="awesome"> 条件がfalseの時に表示される </p>
</div>
javascript部分
let app = new Vue({
  el: '#example',
  data: {
    awesome: false
  }
})
開発者モードのConsole
app.awesome = true
// true
ブラウザの表示
条件がtrueの時に表示される

v-else-if

通常のjavascript同様にv-else-ifでelse ifを記述することが可能です。
v-else-if要素は、v-ifまたはv-else-if要素の直後になければいけません。
それ以外の場合は認識されません。

html部分
<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>
javascript部分
let app = new Vue({
  el: '#example',
  data: {
    awesome: ''
  }
})
ブラウザの表示
条件に当てはまらなった時に表示される
開発者モードのConsole
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 >)要素を使用します。

html部分
<div id="example">
  <template v-if="boxflg">
    <h1>Title</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
  </template>
</div>
javascript部分
let app = new Vue({
  el: '#example',
  data: {
    boxflg: false
  }
})
開発者モードのConsole
app.boxflg = true
// true
ブラウザの表示
Title
Paragraph 1
Paragraph 2
開発者モードのElement
<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つを切り替える入力画面を作ります。

html部分
<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>

正直愚直なコードな気がして最善な書き方では無い気がしますが…

javascript部分
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属性を追加します。

html部分
<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とほとんど同じです。

html部分
<div id="example">
  <p v-show="awesome"> 条件がtrueの時に表示される </p>
</div>
javascript部分
let app = new Vue({
  el: '#example',
  data: {
    awesome: false
  }
})
開発者モードのElements
<div id="example">
  <p style="display: none;"> 条件がtrueの時に表示される </p>
</div>
開発者モードのConsole
app.awesome = true
// true
ブラウザの表示
条件がtrueの時に表示される
開発者モードのElements
<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を同時に利用する事は推奨されておらずバッドプラクティスですということです。
詳細はスタイルガイドを参照してください

参考資料

公式リファレンス

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?