1、执行下面代码
<script src="../../dist/vue.global.js"></script>
<div id="demo">
<h1>
{{count}}
</h1>
</div>
<script>
const { createApp, ref,toRefs, reactive, watch, onMounted,computed} = Vue
var app = createApp({
data(){
return {
count:1
}
},
mounted(){
setTimeout(() => {
this.count++
}, 1000);
}
})
app.mount('#demo')
</script>
2、打断点
src/baseHandlers.ts 的createGetter函数内的track调用,如下图
src/baseHandlers.ts 的createSetter函数内的trigger调用,如下图
3、调用栈分析
首次断点卡在track上,在首次调用render时候读取触发了data响应式数据get
那么什么时候对data做Proxy代理的呢?如下图所示,在初始化setupStatefulComponent内做了响应式处理,
instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers))
instance.data = reactive(data)
在ctx时候,类似于vue2中的this时候,就会触发PublicInstanceProxyHandlers, 在他内部get就会触发data[key],在set触发data[key] = value,也就触发了响应化的data
跳过到下一个断点,就是执行mounted时候this.count++读取count触发track,当然这次的收集依赖是无效的,如下图所示
紧接着再跳过一个断点,如下图所示,触发依赖更新,trigger