Vueでオブジェクトを変更したい時どうするか?
この記事は【Vue】配列の追加・削除には注意が必要👮のオブジェクト版です。
Vueのdata()
関数で返すステート(オブジェクト)についての話。
取得は通常のJSのオブジェクトの操作と同様にキーを使えば問題なかったが、
追加と削除で嵌ったので備忘録として残しておく。
以下、参考にしたページ
次のようなVueコンポーネントのdata()
でcharaObj
という空のオブジェクトを返すとする。
つまり、このコンポーネントでは、初期ステートとしてcharaObj
というオブジェクトが存在することになる。
// 初期状態のステート
export default {
data () {
return {
charaObj: {}
}
}
}
プロパティを追加する
プロパティを追加したい時、通常のJSのオブジェクト同様obj.key = val
とやってしまいたくなるがこれだとリアクティブにデータが反映されない(=データ更新しても画面(HTML)上に反映されない)ので、ダメということらしい。
// リアクティブにデータが反映されないのでこの書き方はダメ
this.charaObj.hero = '範馬刃牙'
プロパティを追加したい時は$set
を使う。
慣れない書き方だが、これでリアクティブにプロパティを追加できる。
第1引数にプロパティの追加先のオブジェクトを、第2引数にキー、第3引数に値を渡す。
// リアクティブになるやつ
this.$set(this.charaObj, 'hero', '範馬刃牙') // => this.charaObj: {hero: '範馬刃牙'}
オブジェクトを追加したい
複数のプロパティをもつオブジェクトを追加したい場合はよくあるだろう。
この場合はスプレッド演算子...
を使って追加したいプロパティを含むオブジェクトを展開すればOK。
this.charObj = {...this.charObj, parent: '範馬勇次郎', friend: '烈海王'}
またはObject.assign()
を使って新しいオブジェクトを作って代入する方法でもできるらしい。
this.charaObj = Object.assign({}, this.charaObj, {parent: '範馬勇次郎', friend: '烈海王'})
プロパティを削除する
追加の時と同じで、いつも通りに削除しようとするとリアクティブにならない。
// リアクティブにデータが反映されないのでこの書き方はダメ
delete this.charaObj.hero
プロパティを削除したい時は$delete
を使う。第1引数に対象のオブジェクトを、第2引数に削除したいプロパティのキーを渡す。
// リアクティブにデータを削除
this.$delete(this.charaObj, 'hero')
全削除したい
最初、空のオブジェクトを再代入で初期化できないかと考えたが、うまくいかなかった。
// 再代入はうまくいかない
this.obj = {}
この場合は、キーの配列をObject.keys()
で取得してループで$delete
を使って削除したところうまくいった。
// プロパティを全削除
Object.keys(this.charObj).forEach(key => {
this.$delete(this.charObj, key)
})
リアクティブにコンポーネントのステートを削除するには先に書いた$delete
を使う。
プロパティを全て入れ替えたい
オブジェクトを一度空にしてからまとめて追加すればよい
オブジェクト自体を削除したい
あまり使うケースは無さそうだが、プロパティではなくステート自体(コンポーネントのトップレベルのプロパティ)を削除したい場合はどうするか?
$delete
を使いたくなるところだが、トップレベルプロパティを削除する時に$delete
を使おうとすると警告が出るので使っちゃダメっぽい。
// トップレベルのプロパティを削除しようとエラーが出る
this.$delete(this, 'charObj')
この場合はnull
を入れればよいみたい。
// charObjを削除する
this.charObj = null