一、Vue 对 data 做了什么
Object.defineProperty
- 可以给对象添加属性
value
- 可以给对象添加
getter / setter
getter / setter 用于对属性的读写进行监控
代理(设计模式)
- 对 myData 对象的属性读写,全权由另一个对象 vm 负责
- 那么 vm 就是 myData 的代理(类比房东租房)
- 比如 myData.n 不用,偏要用 vm.n 来操作 myData.n
vm = new Vue({data: myData})
- 会让 vm 成为 myData 的代理(proxy)
- 会对 myData 的所有属性进行监控
- 为什么要监控,为了防止 myData 的属性变了, vm 不知道,vm 知道了又如何?知道属性变了就可以调用 render(data) !
- UI = render(data)

二、数据响应式
什么是响应式
- 若一个物体能对外界的刺激做出反应,它就是响应式的
- 非侵入性的响应式系统是Vue 最独特的特性之一。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。
Vue 的 data 是响应式
const vm = new Vue({data: {n: 0}})
- 如果修改 vm.n,那么 UI 中的 n 就会响应
- Vue 2 通过
Object.defineProperty 来实现数据响应式
响应式网页
- 如果改变窗口大小,网页内容会做出响应,那就是响应式网页
- 但是要注意,用户没事不会拖动网页大小的
Vue.set 和 this.$set
- 作用
- 新增 key
- 自动创建代理和监听(如果没有创建过)
- 触发 UI 更新(但并不会立刻更新)
- 举例
this.$set(this.object, 'm', 100)
篡改数组的 API
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
你可以打开控制台,然后对前面例子的 `items` 数组尝试调用变更方法
比如 example1.items.push({ message: 'Baz' })
- 这 7 个 API 都会被 Vue 篡改,调用后会更新 UI
- 怎么篡改的
class VueArray extends Array{
push(...args){
const oldLength = this.length
super.push(...args)
console.log('你 push 了')
for(let i = oldLength; i<this.length; i++){
Vue.set(this, i, this[i])
}
}
}
注:这不代表 Vue 的真实实现,仅是举例