学习调试源码,通过一个data响应式实现的问题来探讨:
data: { obj: { foo: “foo” } } 有几个Observer,几个Dep,几个watcher?
调试vue源码
1、State.js:
断点:
1)initData(vm)—53行
2)Observe() --151行—开始对data数据进行响应式
2、进入observe()方法里面进行观察:observe/index.js
开始还没有ob,代码进入124行,新建一个ob = new Observer(value)
1)进入到 Observer(value),Observer过程中又有一个 this.data = new Dep()创建 —创建小秘书
def(value,’ob’,this),添加了’ob,平时console.log()时所看到的,就是在这里添加的
2)walk()–>definedReactive()开始进行数据拦截,
3)又开始对每一个key定义Dep()
4)在此处打断点:obj:{foo:’foooo’}递归
页面上访问:obj.foo 会触发两次访问,第一次是obj,第二次是obj的foo
5)dep.depend()创建和当前weatch的关系
6)把当前的Watcher(id为1)添加进去,就是当前vue的实例。
7)1s钟之后,断点又进入
8)此处打断点:set拦截到(因为改变了值)
9)进入dep.notify() ,通知更新,但是此时界面不会马上更新,因为vue有异步更新策略,有一个队列在管理
2、检测有几个ob
断点1:
文件路径:src/core/observer/index.js
断点2:
src/core/observer/dep.js
断点3:
src/core/observer/watcher.js
开始:
发现第一次调用时 key:’
a
t
t
r
s
’
,
第
二
次
调
用
时
”
attrs’,第二次调用时”
attrs’,第二次调用时”listeners”这两个忽略
开始:
发现第一次调用时 key:’
a
t
t
r
s
’
,
第
二
次
调
用
时
”
attrs’,第二次调用时”
attrs’,第二次调用时”listeners”这两个忽略
1、创建第一个ob
第二个:定义obj这个key
obj实例的小秘书–第三个
第四个
Watcher的实例只创建了一个:
<body>
<div id="demo">
<h1>数据响应化</h1>
<p>{{obj.foo}}</p>
</div>
<script>
//会出现几个Observer? Dep ? Watcher?
//只要出现一个对象就会出现一个ob
//每个key都有一个dep
//每个组件一个watcher
const app = new Vue({
el: "#demo",
data: { obj: { foo: "foo" } },
mounted() { }
});
</script>
</body>
data: { obj: { foo: “foo” } },
所以最终有2个Observer ,4个Dep(因为每创建一个Ob时会生成一个ob,每个key会伴随一个Dep,),1个watcher