LoginSignup
7
3

More than 1 year has passed since last update.

Vue.js 値の変更がビューに検知されない問題

Last updated at Posted at 2021-09-10

Vue.jsでの実務が多くなってきて、ビュー側が変更されない問題が多すぎたので、解消方法一旦まとめました。

公式ドキュメントにもVue2で検知されない変更のパターンはまとめられています
参考リンク → Vue 2 での変更検出の注意事項

オブジェクトの場合

公式ドキュメント

Vue では、すでに作成されたインスタンスに対して新しいルートレベルのリアクティブなプロパティを動的に追加することはできません。

data: {
    user: {
      name: "taro",
      age: 52,
    },
},
methods: {
    changeAge: function(age){
        this.user.age = age; // これだと検知されない
    },
}

解決方法

  • Vue.set使う

Vue.setを使用するとネストされたプロパティに対して、リアクティブな変更が可能になる

methods: {
    changeAge: function(age){
        this.$set(this.user, 'age', age);
    },
}
  • Object.assign()でオブジェクトごとマージしてしまう

MDN Web Docs

Object.assign() メソッドは、すべての列挙可能な自身のプロパティの値を、 1 つ以上のコピー元オブジェクトからコピー先オブジェクトにコピーするために使用されます。変更されたコピー先オブジェクトを返します。

methods: {
    changeAge: function(age){
        const newUser = {...this.user};
        newUser.age = age;
        this.user = Object.assign({}, this.user, newUser);
    },
}

配列の場合

公式ドキュメント

Vue は、配列における次の変更は検知できません:
1. インデックスと一緒にアイテムを直接セットする場合、例えば vm.items[indexOfItem] = newValue
2. 配列の長さを変更する場合、例えば vm.items.length = newLength

data: {
    numbers: [1, 2, 3, 4, 5],
},
methods: {
    changeNumbers: function(number, index){
        this.numbers[index] = number; // これだと検知されない
    },
}

解決方法

  • 要素を追加する場合

    • オブジェクトに関しては、Vue.setで変更しましたが、追加する要素を追加する場合は通常通り、pushで良いらしいです

      破壊的メソッド↓であれば、Vueが監視してくれます

      sort()
      splice()
      push()
      shift()
      unshift()
      reverse()

methods: {
    changeNumbers: function(number){
        this.numbers.push(number);
    },
}
  • 要素の値を置き換える場合

    • splice使って置き換えてあげるとリアクティブな変更になります。

    splice(変更したいindex, 変更する要素数, 変更後の要素);

methods: {
    changeNumbers: function(number){
        this.numbers.splice(index, 1, number);
    },
}

まとめ

オブジェクト・配列のリアクティブな変更の加え方をまとめてみました
この辺の問題もVue3では解決されているらしいので、あまり需要な情報だったかもしれないですね、、

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