オブジェクトの追加には注意が必要
APIで取得してきたオブジェクトをdataで宣言済みのオブジェクトに追加した際に、Cannot read properties of undefined
エラーが出たり、リアクティブに操作できなくてはまったので備忘録。
結論、オブジェクトの追加は$setなどを使う
data() {
return {
test: {
default: {},
},
};
},
mounted() {
this.$set(this.test, "add", {}); // -> リアクティブなadd{}が追加される
},
単純に=
を使ってオブジェクトの追加をしていたのが原因だった。dataの中で宣言しておくか、$setを使って、get/setを持つリアクティブデータとして追加して解決。
解説
vueインスタンスのdataの中に宣言されたものはget/setを持ち、何かしら変更があったら感知ができるリアクティブなデータになる。
dataの中で宣言したものはリアクティブなものだが、=
などで後から追加されたオブジェクトはget/setを持たない、非リアクティブなデータ。
下記サンプルコードで確認してみる。
data() {
return {
test: {
default: {},
},
};
},
mounted() {
this.test.add = {};
this.$set(this.test, "add2", {});
console.log(this.test);
},
dataの中で宣言していた、default: {}
はget/setを持つリアクティブデータ。
=
で単純に追加したadd: {}
はget/setを持たない非リアクティブデータ。
$set
を使って追加したadd2: {}
はget/setを持つリアクティブデータであることがわかる。
まとめ
リアクティブなデータを追加していかないと、予期せぬエラーになる。
なのでデータを追加する際には$set
を使って、get/setを持つリアクティブデータで追加する。
公式を見るとObject.assign()
や _.extend()
でも追加できるよう。
公式:リアクティブの探求