变化检测顾名思义就是检测数据发生变化时,响应数据的更新。
它分为两种类型:一种是推,一种是拉;Angular 和 React 的变化检测都属于’拉‘。就是说,当状态发生变化时,它不知道哪个状态发生变化,就发送一个信号给框架,框架使用暴力检测 DOM 来更新状态。这也是 Angular 脏检查的原理,React 使用虚拟 DOM 的原理。
而 Vue.js 是使用’推‘的形式,就是一定程度上知道哪个状态发生了变化,从而进行更新。但是它的依赖相对来说也会比较多。
有两种方式可以检测到变化:Object.defineProperty 和 ES6 的 Proxy。
Object.defineProperty(obj, prop, desc)
**Object.defineProperty() 的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。**
obj 需要定义属性的当前对象
prop 当前需要定义的属性名
desc 属性描述符
如:let Person = {}
Object.defineProperty(Person, 'name', {
value: 'jack',
writable: true // 是否可以改变
configurable:true
})
由于 ES6 在浏览器的支持度不是很理想,所以 Vue.js(2.x.x)是用 Object.defineProperty 来实现的。
Vue 在初始化实例时对属性执行了 getter/setter 的转化,所以属性必须在 data() 上才能被 Vue 转化成响应式。( 深入响应式原理)