Vue.js 3 Composition APIでオブジェクトのプロパティをリアクティブに追加ができない時

reactive と ref の基本

Vue 3のComposition APIでデータのリアクティビティを実現するためのメソッドに
reactiveとrefがあります。これらを使用して作成されたデータはリアクティブになり、変更を監視することができます。

reactiveとrefにおけるリアクティビティのはまりポイント

オブジェクトへの新しいプロパティの追加

reactiveやrefで作成されたオブジェクトに新しいプロパティを動的に追加する場合、そのプロパティはリアクティブではありません。初期化時にreactiveに渡されたオブジェクトのプロパティのみがリアクティブに監視されます。

const state = reactive({ a: 1 });
state.b = 2;  // リアクティビティがない

解決策

reactiverefでラップされたオブジェクトに新しいプロパティを追加する際、新しいオブジェクトを生成してスプレッド演算子を使用することで、新しいプロパティも含めてリアクティブなオブジェクトを取得することができます。

const state = reactive({ a: 1 });
state = { ...state, b: 2 };  // 新しいプロパティbを追加

const refState = ref({ x: 1 });
refState.value = { ...refState.value, y: 2 }; // 新しいプロパティyを追加

toRefsを使用することでreactiveオブジェクトの各プロパティを個別のrefとして取得することもできます。reactiveオブジェクトを新しいオブジェクトとマージすることで、新しいプロパティもリアクティブに保つことができます。

import { reactive, toRefs, ref } from 'vue';

const state = reactive({ a: 1 });
const refs = toRefs(state);
const newState = { ...refs, b: ref(2) }; // 各プロパティがrefとして展開され、新しいプロパティbも追加
console.log(newState.a.value) // 1
console.log(newState.b.value) // 2

refでラップされたオブジェクトの中身を更新する場合、直接refを再代入するのではなく、.valueを使って更新することで、オブジェクトのリアクティブ性を維持することができます。

import { ref } from 'vue';

const obj = ref({ prop: 'initial' });
obj.value.prop = 'updated';  // 正しい方法でプロパティを更新

console.log(obj.value); // { prop: 'updated' }

// 間違った方法
obj = ref({ prop: 'new object' });  // これはobj全体を再代入してしまっている

console.log(obj.value); // { prop: 'new object' }
console.log(obj.value.prop); // 'new object'

下記はobjに新しいrefオブジェクトを再代入しています。したがって、objは新しいrefオブジェクトを指すようになり、以前のrefオブジェクトへの参照を失います。

// 間違った方法
obj = ref({ prop: 'new object' });  // これはobj全体を再代入してしまっている

まとめ

Vue 3のComposition APIはreactiverefの使い分けが難しい上にオブジェクトのリアクティビティには注意点がいくつか存在します。
効果的に使っていきたいものです。。

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。