Vue.js 是一款 MVVM 框架,数据模型仅仅是普通的 JavaScript 对象,但是对这些对象进行操作时,却能影响对应视图,它的核心实现就是响应式系统
Object.defineProperty
vue.js 的响应式系统是基于它实现的! Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
参数:Obj 要在其定义属性的对象
prop:要定义或修改的属性名称
descriptor : 将被定义或修改的属性描述符
描述:
该方法允许精确添加或修改对象的属性。通过赋值来添加的普通属性会创建在属性枚举期间显示的属性(for...in或Object.keys方法), 这些值可以被改变,也可以被删除。这种方法允许这些额外的细节从默认值改变。默认情况下,使用Object.defineProperty()添加的属性值是不可变的。
属性描述符:
enumerable,属性是否可枚举,默认 false。
configurable,属性是否可以被修改或者删除,默认 false。
get,获取属性的方法。
set,设置属性的方法。
使数据对象变得“可观测( observer )
我们定义一个数据对象,就以王者荣耀里面的其中一个英雄(我最爱的夏侯惇,一把刀切死,尴尬段位还是在铂金。。。。。。)
回归正题:
const hero = {
health: 3000,
IQ: 150
}
我们可以直接读写这个英雄的属性!但是我们并不知情!如何让夏侯惇直接告诉我们呢!这时候需要借助Object.defineProperty() 超级兵的帮助!
以上只是生命值health 和 IQ可以观测 !为了把英雄的所有属性可以实现观测
让我们用 observer 来封装一个 Vue 吧!
观察者 Watcher
现在,英雄已经变得可观测,任何的读写操作他都会主动告诉我们,但也仅此而已,我们仍然不知道他是谁。如果我们希望在修改英雄的生命值和IQ之后,他能够主动告诉他的其他信息,这应该怎样才能办到呢?假设可以这样
我们定义了一个watcher作为“监听器”,它监听了hero的type属性。这个type属性的值取决于hero.health,换句话来说,当hero.health发生变化时,hero.type也应该发生变化,前者是后者的依赖。我们可以把这个hero.type称为“计算属性”。
那么,我们应该怎样才能正确构造这个监听器呢?可以看到,在设想当中,监听器接收三个参数,分别是被监听的对象、被监听的属性以及回调函数,回调函数返回一个该被监听属性的值。顺着这个思路,我们尝试着编写一段代码:
我们现在是通过手动读取hero.type来获取这个英雄的类型,并不是他主动告诉我们的。如果我们希望让英雄能够在health属性被修改后,第一时间主动发起通知,又该怎么做呢
为什么要依赖收集?
先举个栗子🌰
假如你修改了kai3=121; 但是视图中并没有用但 watcher 就不会更新视图
假如说实例了两个vm1 vm2 改变的是name的值后 你得知道是谁,那两个地方要修改 因此有依赖收集
网友评论