【Vue】オブジェクト追加・削除には注意が必要👮 の配列版です。
オブジェクトと同じく、参照するだけなら普通のJSと同だが、要素の追加・削除で嵌るポイントがあった。
既に同様の記事はあるが自分用の備忘録という意味を含めて残すことに。
↓の記事も参考に。
次のようなVueコンポーネントのdata()
関数でcharas
という空の配列を返すとする。
つまり、このコンポーネントの初期状態ではステートとしてcharas
配列が存在することになる。
// 初期状態のステート
export default {
data() {
return {
charas: []
}
}
}
要素を追加する
オブジェクトでは$set
を使ったが、配列では追加するときは末尾であれば通常通りpush()
でOKらしい。先頭に追加などは試していないのでわからず。
// いつも通り`push`を使えばOK
this.charas.push('範馬刃牙')
配列を追加したい
要素をまとめて追加したい場合、既にある配列をステートに追加するという場面はよくあるだろう。
この場合はスプレッド演算子...
を使って配列を展開した要素をpush()
で追加すればまとめて追加できる。
配列でない場合はArray.prototype.push
は複数の引数を受け取ることができるので、そのまま渡せば良い。
// 配列を追加する
this.charas.push(...['範馬勇次郎', '烈海王'])
this.charas.push('範馬勇次郎', '烈海王')
要素を変更する
要素を変更したい時、いつも通りインデックスを使ってしまいたくなるがこれだとリアクティブにデータが反映されない(=データ更新しても画面(HTML)上に反映されない)。
splice()
を使う。
構文は<配列>.splice(<始まりのインデックス>, <変更する要素数>, <変更後の要素>)
と書くとのこと。
(書き方をいつも忘れてしまう)
見ての通り複数個まとめて変更することもできる。
// これはリアクティブにならない(=ステート変更を行った時にHTMLに変更が反映されない)
this.charas[0] = '範馬勇一郎'
// これだとリアクティブになる
this.charas.splice(0, 1, '範馬刃牙')
要素を削除する
変更のときと一緒でsplice()
を使う。
書き方は<配列>.splice(<始まりのインデックス>, <削除する要素数>)
見ての通り複数の要素をまとめて削除できる。
ちなみに戻り値は削除した要素を含む配列で破壊的メソッドとして働く。
// リアクティブにデータを削除
this.charas.splice(0, 2) // => インデックス0, 1の要素を含む配列が戻り値
全削除したい
通常通り、arr.length = 0
のイディオムを使いたくなるが、これだと配列の長さを変える操作なのでうまくいかないらしい。
(一見、動いているようにみえるケースもあったが、Vue作者もそう言っているので使うのはやめた方がよさそう)
// これはリアクティブにならない(=ステート変更を行った時にHTMLに変更が反映されない)可能性がある
this.charas.length = 0
要素をまとめて削除できるsplice()
を使う。第二引数に配列の長さを渡せば全削除できる。
// これでリアクティブに全削除できる。
this.charas.splice(0, this.charas.length) // => []
要素を全て入れ替えたい
配列を一度空にしてからまとめて追加すればよい
// 一旦、全削除して要素を入れ替える
this.charas.splice(0, this.charas.length)
this.charas.push(...['範馬刃牙', '範馬勇次郎', '烈海王'])
配列自体を削除したい
あまり使うケースは無さそうだが、要素ではなく配列自体を削除したい場合はどうするか?
この場合はオブジェクトと同じでnull
を入れればよいみたい。
// charasを削除する
this.charas = null