背景
前几天被问到了关于 vue2 和 vue3 双向绑定这部分的区别,总觉得自己很熟悉,但是不能用言语表达。于是呼,希望通过这篇文章整理一下。
vue2
1. Object.definedProperty()
Object.definedProperty() 是 es5 的属性,其通过 get() 和 set() 方法劫持数据的读写。
2. 对 data 数据进行遍历
每个组件都有一个 data 选项,当组件渲染过程中,会对 data 数据进行遍历,用 Object.defineProperty 转为 getter/setter。data 之后添加的属性不能 observe
- data 数据中存在对象,进行遍历递归
- data 数据中有数组,如果数组元素为对象,重复1。没有则进行特殊处理
3. 针对数组需要额外处理
Vue 不能检测两种改变
- 利用索引直接改变,es6改变时数组实例的方法
- 修改数组长度
Object.definedProperty() 不能实现直接对数组的监听,只接受七种方法,本质上这七种方法也是通过源码重写这写方法触发更新,上述的两种是实现性价比低。
push() pop() shift() unshift() splice() splice() sort() reverse()
复制代码
对应的解决的方法
- Vue.Set(this.arr, index, newValue) 或者 深拷贝新的值覆盖
- this.arr.splice(newLength)
需要说明的一点是:不能检测变动指的是 watcher 实例不能检测到,页面上的数据还是能检测到的。不过为了避免watcher实例和页面不一致,避免使用不能检测的改变而采用对应解决方法
vue3
1. Proxy()
Proxy() 是 es6 的构造函数,用于拦截外界对目标对象的读写。不需要进行遍历
2. ref() reactive()
ref() reactive() 随时可以添加
3. 不需要对数组进行额外处理
Proxy() 可以实现对数组的监听
总结
-
vue2 和 vue3 双向绑定根据区别在于使用不同方法对数据进行监听,而导致的监听方式和监听特点的不同。
-
vue2 中针对 es5 数组方法会改变原数组的方法进行处理,但是没有对 es6 中改变原数组的方法进行处理。