LoginSignup
32
14

More than 1 year has passed since last update.

【Vue.js】`v-for`, `v-if` を一緒に使うのは避けよう

Last updated at Posted at 2020-08-24

はじめに

Vue.jsスタイルガイドによると、v-ifv-for を一緒に使うのは避けるべきとされています。

一緒に使うというのは

vuejs/hoge.vue

<template v-for="item in items"  v-if="item.key === 1" :key="item.id">
      <li>
        <router-link :to="item.url">{{ item.pages }}</router-link>
      </li>
 </template>

上記のような、同一のタグの中にv-forとv-ifを詰め込んでいる状態のことを指しています:point_up_2_tone2:

とある記事のコメントにてv-forとv-ifの併用を勧めてしまって、(もちろん訂正コメントも送信しています:ok_hand:
今後同じことを勧めないようにアウトプットで書きました。

なぜだめなのか

Vue がディレクティブを処理するとき、v-forは v-if よりも優先度が高いとされていて
上の例の中身の処理をJavaScriptで書くと

JavaScript/hoge.js
this.items.map(function (item) {
  if (item.key === 1) {
    return item.url
  }
})

このようになります
これだとresultに変更があった際に実際に表示されるitemの変更の有無にかかわらず
再度繰り返し処理されるのです:imp:

じゃあどうしたいいんか

実際に表示されるitemに変化があったり条件に合うitemが増減したりする際にのみ
繰り返し処理を行うようにします。:pig_nose:

vuejs/hoge.vue
<ul>
  <li v-for="item in resultKey">
    <router-link :to="item.url">{{ item.pages }}</router-link>
  </li>
</ul>

~~~省略

computed: {
  resultKey: function () {
    return this.items.filter(function (item) {
      return  item.key  === 1
      }
    })
  }
}

今回は算出プロパティを使って解決しました。
こうすることで以下の利点が得られます:moneybag:

フィルタリングされたリストは items 配列に関連する変更があった場合に のみ 再評価されるので、フィルタリングがはるかに効率的になります。
v-for="item in activeUsers" を使用して、描画中にkeyが1のitem のみ 繰り返し処理するので、描画がはるかに効率的になります。
ロジックがプレゼンテーションレイヤから切り離され、メンテナンス(ロジックの変更/拡張)がはるかに容易になります。
(参照: Vue.js スタイルガイド v-for-と一緒に-v-if-を使うのを避ける-必須

おわり

Vue.jsって結構なんでもできちゃうのでおっこれでいけるじゃん!と思っていたものは実は推奨されていない書き方って結構あるかもですね(ドキュメントしっかり読んでいるからそんなことないわって思っている方もいるかもですが)
つまりドキュメント最強です
これ大丈夫なのかって思ったらとりあえずドキュメントですね:writing_hand_tone4:

参照記事

Vue.jsドキュメント スタイルガイド

32
14
1

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
32
14