Vue.js で配列を扱う際は「リアクティブシステムが変更を検知できるか」が鍵になる。以下では、配列を安全かつ効率的に更新するための実践的なテクニックを紹介する。
1. リアクティブに動作する破壊的メソッド
Vue は次の 7 つのメソッドをラップしており、呼び出し時に自動的に DOM を更新する。
push/popunshift/shiftsplicesortreverse
// 末尾に追加
this.taskList.push({ title: '買い物', done: false });
// 先頭に複数追加
this.taskList.unshift(
{ title: 'メール返信', done: false },
{ title: 'レポート作成', done: false }
);
// インデックス 2 から 1 件削除して新しい要素で置換
this.taskList.splice(2, 1, { title: '会議準備', done: true });
2. 非破壊メソッドで新しい配列を返す
filter・concat・slice は元の配列を変更せず、新しい配列を返す。Vue に変更を通知するには、戻り値を再代入する。
// 完了タスクだけを抽出
this.taskList = this.taskList.filter(todo => !todo.done);
// 別の配列を結合
this.taskList = this.taskList.concat([
{ title: 'プレゼン資料', done: false },
{ title: '経費精算', done: false }
]);
// 先頭 3 件だけを切り出して表示用にする
this.displayList = this.taskList.slice(0, 3);
3. インデックスや length への直接代入を回避
次のような操作はリアクティブシステムが追跡できないため、DOM が更新されない。
// ❌ 非リアクティブ
this.taskList[1] = { title: '更新タスク', done: false };
this.taskList.length = 0;
対処法は以下の 3 パターン。
// ✅ Vue.set / this.$set を使用
this.$set(this.taskList, 1, { title: '更新タスク', done: false });
// ✅ splice で置換
this.taskList.splice(1, 1, { title: '更新タスク', done: false });
// ✅ splice で全削除
this.taskList.splice(0);
4. 実践サンプル:ToDo リスト
<template>
<div>
<input v-model="newTitle" @keyup.enter="addTask">
<button @click="addTask">追加</button>
<ul>
<li v-for="(t, idx) in taskList" :key="t.id">
<input type="checkbox" v-model="t.done">
{{ t.title }}
<button @click="removeTask(idx)">削除</button>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
newTitle: '',
taskList: []
};
},
methods: {
addTask() {
if (!this.newTitle.trim()) return;
this.taskList.push({
id: Date.now(),
title: this.newTitle,
done: false
});
this.newTitle = '';
},
removeTask(index) {
this.taskList.splice(index, 1);
}
}
};
</script>
上記コードでは、push と splice を用いることで、リアクティブな更新が保証されている。