又是这个面试题,是时候好好总结以下怎么回答了!
vue2的响应式原理有几个概念:
-
观察者:template 里诸如
{{ message }}、{{ name }}等等都会创建一个观察者。观察者们的任务是负责展示最新数据,但是,它们本身没有这种能力,所以暴露了一个方法,这个方法接收新数据并展示。这样,外界就可以通过这个方法,让观察者展示新数据了。 -
数据:创建vue实例时,需要提供一份
data:{message,name},这些data就是观察者依赖的数据。我们需要判断,这些数据什么时候更新,好通知对应的观察者。这里就涉及到两方面:数据什么时候更新、通知对应的观察者。
JavaScript提供了Object.defineProperty方法,这个方法用来在一个给定的对象上定义新属性,可以指定value configurable enumerable get set等一系列属性特征。其中,get是新属性的getter, set是新属性的setter。
所以,vue创建了一个空对象,然后把data里的属性(除了数组)一一定义到了空对象上,同时指定了它们的get set。由此实现了数据更新通知对应的观察者。
通知哪些观察者?
vue分了3步走。
- 在创建观察者时,把这个观察者赋值给一个全局变量。
- 去尝试获取依赖,这个时候,就会执行指定的
getter。getter函数去拿到全局变量里的观察者,保存起来。 这里可以思考下,这个全局变量怎么存?
答案揭晓:可以用一个字典存。字典键为 属性名,值为观察者数组。
数据什么时候更新?
不知道,但是,数据更新的时候,会执行我指定的
setter。
- 根据键值,从字典里把观察者数组拿出来。
- 数组里每个观察者一一执行更新接口。
vue将观察者数组抽象成了一个类,称为deps,提供了一些操作方法,比如增加观察者、删除观察者、观察者数组遍历执行更新。