
前言
Vue.js的核心包括一套“响应式系统”。
“响应式”,我打你一拳,你会喊疼,那你就是响应式。若一个物体能对外界的刺激作出反应他就是响应式的。
当数据改变后,Vue会通知到使用该数据的代码。视图渲染中使用了数据,数据改变后,视图也会自动更新。
基本概念
Vue的相应式,核心机制是观察者模式。
数据是被观察的一方,当数据发生改变,通知所有的观察者,这样的观察者可以作出响应,比如,重新渲染然后更新视图。
我们把依赖数据的观察者称为 watcher,可以表示为:
data -> watcher
Vue通过在 data 和 watcher 间创建一个dep对象,来记录这种依赖关系:
data - dep -> watcher
dep的结构很简单,除了唯一的标识属性id,另一个就是记录所有观察者的subs:
id - number
subs - [Watcher]
正文:
Vue.js的响应式原理依赖于Object.defineProperty,Vue通过设定对象属性setter/getter方法来监听数据的变化,通过getter进行依赖收集,而每个setter方法就是一个观察者,在数据变更的时候通知订阅者更新视图。
一、Vue对Data做了什么?
示例代码:
const Vue = window.Vue
const myData = {
n:0
}
new Vue({
data: myData,
template: `
<div>{{n}}</div>
`
}).$mount('#app')
setTimeout(() => {
myData.n += 10
}, 0)
console.log(myData)
在myData 传给 Vue 的时候 ,数值就会发生改变。

myData变了,一开始是{n:0},传给new Data之后立马变成{n:(...)}。
vue监听了这个数值,vue 会让 vm 成为 myData 的代理,vue 会对 myData 的所有属性进行监控,当数值发生改变的时候,vue就重新渲染。
而原理是把一个普通的 JavaScript 对象传入 Vue 实例作为data选项,Vue 将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter。Object.defineProperty是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在属性被访问和修改时通知变更。
二、数据响应式
- 响应式即对外界的变化做出的反应的一种形式。
- const vm = new Vue({data:{n: 0}})。
- 当修改 vm.n 或 data.n 时,render(data...) 中的 n 就会做出响应的响应。
- 这个联动的过程就是 vue 的 数据响应式。
- vue 目前通过 Object.defineProperty 来实现数据响应式。