vue3处理data流程分析

140 阅读1分钟

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调用,如下图

image.png

src/baseHandlers.ts 的createSetter函数内的trigger调用,如下图

image.png

3、调用栈分析

首次断点卡在track上,在首次调用render时候读取触发了data响应式数据get

image.png

那么什么时候对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

image.png

跳过到下一个断点,就是执行mounted时候this.count++读取count触发track,当然这次的收集依赖是无效的,如下图所示

image.png

紧接着再跳过一个断点,如下图所示,触发依赖更新,trigger

image.png