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()
でオブジェクトごとマージしてしまう
Object.assign() メソッドは、すべての列挙可能な自身のプロパティの値を、 1 つ以上のコピー元オブジェクトからコピー先オブジェクトにコピーするために使用されます。変更されたコピー先オブジェクトを返します。
methods: {
changeAge: function(age){
const newUser = {...this.user};
newUser.age = age;
this.user = Object.assign({}, this.user, newUser);
},
}
配列の場合
公式ドキュメント
Vue は、配列における次の変更は検知できません:
- インデックスと一緒にアイテムを直接セットする場合、例えば vm.items[indexOfItem] = newValue
- 配列の長さを変更する場合、例えば 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では解決されているらしいので、あまり需要な情報だったかもしれないですね、、