关于 vue2 vue3 响应式数据,及如何清空、重置对象

在一个项目中,后台用的 vue3,前端用的是 uniapp vue2,项目几乎是并行开发,然后在一个vue2 数据清空的方法里直接写了一个 this.form = {}的代码,结果页面出现残留数据

让我进一步了解了 vue2 响应式系统,以及 vue3 的 proxy 特性

vue2 响应式

vue2的响应式系统是基于 getter 和 setter 工作的。在数据对象初始化的时候,vue 会通过object.defineProperty将每个属性转为 getter 和 setter,试 vue 能够追踪属性的变化,并在属性发生变化时更新视图;

vue2 直接赋值 this.form = {} 会创建新的对象,vue2响应式系统不会自动检测对象的替换,只会在对象的已有属性发生变化时更新视图,而不会追踪对象本身的替换,所以页面仍然可能保留旧的数据。

新增属性追踪问题

如果你向一个已有的对象中新增属性,vue2 是无法检测到新添加的属性变化,因为 vue 在初始化时只会在对象已有的属性上设置 getter 和 setter,之后的新增属性vue时不会追踪,也就是说新增属性不是响应式数据,无法触发试图更新!

解决方案

1、
Object.keys(this.form).forEach(key => {
  this.form[key] = ""; // 清空每个字段,而不是替换整个对象
});

2、
for (let key in this.form) {
  this.$set(this.form, key, null);  // 或者设置为空字符串、0 或其他适当值
}

vue3 的 Proxy

使用的 ref 定义响应式数据,清空数据可以直接写成 form.value = {}

vue3的响应式系统是基于 proxy 的,通过 ref 创建的对象会在内部进行代理,通过 form.value = {},虽然是重新赋值一个新对象给 form,这个新对象仍然是响应式的,因此会检测到 form 的变化,在页面中相应更新

如果使用的是 reactive 创建的对象,应该使用 Object.assign(form, {}) 清空对象内容,而不是直接赋值空对象,因为 reactive 会在原始对象应用代理,替换整个对象会打破响应式连接;

proxy

是 vue3 中用来实现响应式数据的核心技术之一,用来创建代理对象,在不改变原始对象的情况下,对对象的行为进行自定义操作,通过本身提供的拦截器(如 get,set 等)来拦截和处理对目标对象的操作。

你可能感兴趣的:(前端,javascript,vue.js)