0
0

More than 3 years have passed since last update.

配列・オブジュエクトの変更をリアクティブに検出するには

Posted at

数字や文字列などは簡単に検出できるが、配列・オブジェクトは一工夫必要

TL;DR

Vue.set() を利用して変更させる

やってみる

直接変更させた場合

<template>
  <div class="center">
    <div class="row">
      <div v-if="bool">ON</div>
      <div v-else>OFF</div>
      <button @click="bool = !bool">真偽値</button>
    </div>
    <div class="row">
      <div v-if="array[0]">ON</div>
      <div v-else>OFF</div>
      <button @click="array[0] = !array[0]">配列</button>
    </div>
  </div>
</template>

<script>
export default {
  layout: 'plain',
  data() {
    return {
      array: [false],
      bool: false
    }
  }
}
</script>

<style>
.center {
  width: 100px;
  margin: 0 auto;
}

.row {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
}
</style>

sample1.gif

単体のboolは値の変更に合わせて表示も切り替わるが、配列はそうもいかない(配列の値自体は変わっている)

配列の値をVue.set()で変更させる

中身を直接変更するのではなく、 Vue.set(Array, index, value) を利用してみる。
ここの例では、エイリアスである this.$set() にしています。

詳しいドキュメントはこちら

<template>
  <div class="center">
    <div class="row">
      <div v-if="bool">ON</div>
      <div v-else>OFF</div>
      <button @click="bool = !bool">真偽値</button>
    </div>
    <div class="row">
      <div v-if="array[0]">ON</div>
      <div v-else>OFF</div>
      <!-- 配列の値の変更の仕方を変える -->
      <button @click="changeValue()">配列</button>
    </div>
  </div>
</template>

<script>
export default {
  layout: 'plain',
  data() {
    return {
      array: [false],
      bool: false
    }
  },
  methods: {
    changeValue() {
      this.$set(this.array, 0, !this.array[0])
    }
  }
}
</script>

<style>
/* 省略 */
</style>

sample2.gif

いいかんじ!

まとめ

Vueでは配列の中身や長さ、オブジェクトのプロパティの追加や削除の検出ができないため、それを可能にするためにVue側でメソッドが用意されていたんですね。

意外とこれに気づかずに実装を進めて、後々になって「何でここだけ動いてないん...?」となったのは自分の他にもいるんじゃないでしょうか...

備考

0
0
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
0
0