双向绑定
- 发布-订阅
- 脏检测
- 数据劫持
- Object.definePropery (es5)
- Proxy (es6)
- Object.observe(废弃)
- 数据模型
definePropery
1. 不能检测数组长度变化,准确的说是通过改变Length而增加的长度不能检测。
length 和数字下标之间的关系 —— JavaScript 数组的 length 属性和其数字下标之间有着紧密的联系。数组内置的几个方法(例如 join、slice、indexOf 等)都会考虑 length 的值。另外还有一些方法(例如 push、splice 等)还会改变 length 的值。为什么defineProperty不能检测到数组长度的“变化”
- 当你利用索引直接设置一个项时,vm.items[indexOfItem] = newValue
1. 解决方法:Vue.set(vm.items, indexOfItem, newValue) / vm.$set(vm.items, indexOfItem, newValue) / vm.items.splice(indexOfItem, 1, newValue) - 当你修改数组的长度时,vm.items.length = newLength
1. 解决方法:vm.items.splice(newLength)
2. 为什么defineProperty不能检测到数组长度的“变化”
1.
3. vue对数组方法的hack
1 | const arrayProto = Array.prototype |
4. Vue 不能检测对象属性的添加或删除
- 对于已经创建的实例,Vue 不能动态添加根级别的响应式属性
1 | var vm = new Vue({ |
- 解决方法:
- Vue.set(vm.userProfile, key, value)
- vm.$set(vm.userProfile, key, value)
- Object.assign()
5. definePropery缺点
- 无法监听数组变化
- 无法检测对象属性的添加和删除
- 性能差。只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历,如果属性值也是对象那么需要深度遍历
Proxy
Proxy可以直接监听对象而非属性
1 | const input = document.getElementById('input'); |
Proxy可以直接监听数组的变化
优缺点
- 优点:对数组和对象支持非常好,不需要hask;性能比definePropery好,初始化很多数据,当用到才会被监听。
- 缺点:兼容性不太好,而且无法用polyfill磨平