数据响应式概念
- 响应式即对外界的变化做出的反应的一种形式。
- const vm = new Vue({data:{n: 0}})
- 当修改 vm.n 或 data.n 时,render(data…) 中的 n 就会做出响应的响应。
- 这个联动的过程就是 vue 的 数据响应式。
- vue 目前通过 Object.defineProperty 来实现数据响应式
- vm相当于data的代理
Vue响应式方法
Object.defineProperty
- 可以给对象添加属性value
- 可以给对象添加getter/setter,用于对属性的读写进行监控
代理
- vm=new Vue({data:myData})
- 让vm成为myData的代理(proxy)
- 会对myData的所有属性进行监控
- 监控目的:防止myData的属性变了,vm不知道
- vm知道属性改变才可以调用render(data)
- UI=render(data)
Vue响应式bug
Object.defineProperty的问题
- Object.defineProperty(obj,‘n’,{……})
- obj中必须有’n’,才能监听和代理obj.n
- 若obj中没有n,则监听不到
- 因为vue无法监听一开始就不存在的obj中的属性
解决办法
- 在对象中把key都声明好,后面再加属性(不现实)
- 使用Vue.set或this.$set
Vue.set和this.$set作用
- 新增key
- 自动创建代理和监听(如果没有创建过)
- 触发更新UI(但不会立刻更新)
数组变异
data中有数组怎么办?
- 数组的长度可以一直增加,下标就是key
- 没有办法把数组的key都提前声明出来
- 每次都使用Vue.set显然不现实
尤雨溪修改了数组的API,详见数组更新检测
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
总结
对象中新增的key
- Vue没有办法事先监听和代理
- 要使用set来新增key,创建和监听代理,更新UI
- 最好提前把属性都写出来,不要新增key
- 但数组做不到“新增key”
数组中新增key
- 也可用set来新增key,更新UI
- 不过尤雨溪修改了7个API方便对数组进行增删
- 这7个API会自动处理监听和代理,并更新UI
- 结论:数组新增key最好通过7个API