LoginSignup
61
40

More than 5 years have passed since last update.

[Vue.js/Nuxt.js] v-forで中の要素にcomputedを使いたいときはコンポーネント分割をしよう

Last updated at Posted at 2019-03-24

概要

Vueの算出プロパティであるcomputedは引数を持つことができず、v-forで回しているArray[Index]のような一部の要素のみを指定することができない。

一応、methodsに書いて呼び出すことで擬似的に動作させることは可能だが、状態が変わったときに再計算が行われないのが結構落とし穴である。

以下のコードは、コメント一覧画面でv-forでArrayのコメント一覧を回し、コメント1つ1つに対して閲覧者であるユーザのコメントがあったらそのコメントのみModifierのclassを付与したいという場合のサンプルコードである。

動作しないコード

computedは引数を持つことができないので、以下のコードはエラーとなる。

Comments.Vue
<template>
  <div v-for="(comment, comments)" class="comments">
     <p class="comments__comment" :class="isUserPostClass(comment)"/>
  </div>
</temlate>

~省略
  computed: {
    isUserPostClass(comment) {
      return comment.isUserPost ? 'comments__comment--user-post' : '';
    }
  }
~省略

動作するが良くないコード

methodsに定義すれば引数を取得でき、動きはするが再計算がされないので複数回の描画の際に積む。
(たとえば、クリックしたらそのコメントが強調されるようにしたいなどの要件に対応できない)

Comments.Vue
<template>
  <div v-for="(comment, comments)" class="comments">
     <p class="comments__comment" :class="isUserPostClass(comment)"/>
  </div>
</temlate>

~省略
  methods: {
    isUserPostClass(comment) {
      return comment.isUserPost ? 'comments__comment--user-post' : '';
    }
  }
~省略

解決策

ではどうすればいいのかと言うと、タイトルにもある通りv-forの中身だけをコンポーネント分割すればOKである。
今回はコメント一覧画面なので、コメント単体のコンポーネントを作成し、propsにv−forで回しているコメントのObject、および変更を検知させて再計算させたいプロパティをを与えてあげれば問題ない。

その後、コメントコンポーネントの中でcomputedを定義すれば、v-forの中身でcomputedを使うことができる。

動作するコード

Comments.Vue
<template>
  <div v-for="(comment, comments)" class="comments">
     <UserComment :comment="comment" :isUserPost="comment.isUserPost" />
  </div>
</temlate>
UserComment.Vue
<template>
  <div class="user-comment" :class="isUserPostClass">
     ~内容~
  </div>
</temlate>

~省略
  props: {
    comment: {
      type: Object,
      default: null
    },
    isUserPost: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    isUserPostClass() {
      return this.isUserPost ? 'user-comment--user-post' : '';
    }
  }
~省略

まとめ

  • v-forの中でcomputedを使いたくなったら、ループ対象であるDOMをコンポーネント分割しよう
  • computedでプロパティの内容が変わったときの再計算処理を走らせるためには、明示的にpropsとして渡したほうが安全
61
40
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
61
40