Vue 3 中的 Object.assign 与响应式丢失问题
Vue 3 的响应式原理
Vue 3 使用 Proxy 来创建响应式对象:
javascript
// Vue 3 使用 Proxy 来创建响应式对象
const formState = reactive({
name: '',
age: 0
});
// 这时 formState 的现有属性是响应式的
Object.assign 的问题
javascript
// 错误示例
Object.assign(formState, {
name: 'John',
newProp: 'value' // 新属性不会被转换为响应式
});
// 正确示例
formState.name = 'John'; // 已存在的属性会保持响应式
为什么会丢失响应式
Object.assign
是直接复制属性,绕过了 Vue 的响应式系统- 新添加的属性不会自动变成响应式
- 只有在创建
reactive
对象时声明的属性才会被正确追踪
正确的更新方式
javascript
// 方式1:逐个赋值
Object.keys(newData).forEach(key => {
if (formState.hasOwnProperty(key)) {
formState[key] = newData[key];
}
});
// 方式2:使用解构赋值
const { name, age } = newData;
formState.name = name;
formState.age = age;
// 方式3:如果确实需要添加新属性,使用 ref 或 reactive
const newFormState = reactive({
...formState,
newProp: 'value'
});
实际应用示例
javascript
// 在组件中的正确使用方式
const formState = reactive({
name: '',
age: 0,
// 预先定义所有可能的属性
additionalInfo: null
});
const updateFormState = (newData) => {
// 安全地更新现有属性
Object.keys(formState).forEach(key => {
if (newData[key] !== undefined) {
formState[key] = newData[key];
}
});
};
最佳实践建议
- 预先声明所有可能的属性
- 使用逐个赋值的方式更新数据
- 如果需要添加新属性,考虑重新创建响应式对象
这样可以确保数据的响应式特性被正确维护。