「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。
前言
这部分内容对于新入坑阅读源码的小伙伴们来讲还是有些复杂的,我们这部分主要会采取分析调用栈信息(从最后一步的位置打断点,运行后看调用栈信息)、单步执行之后,再进入代码部分来阅读源码。
整体思路
我们先来回顾以下之前分析的整体流程,在初始化的时候,曾经做过的事情是什么?下图:
有一个方法setupRenderEffect,此方法会建立更新机制。
初始化
我们可以在example部分再穿件一个02-patch.html,内容如下
<div id="app">
<h1>vue3 更新流程</h1>
<p>{{counter}}</p>
<comp></comp>
</div>
<script src="../dist/vue.global.js"></script>
<script>
// vue2: new Vue({})
// 变化1:函数创建实例
// vue3 createApp({})
const app = Vue.createApp({
data() {
return {
counter: 1
}
},
mounted() {
setInterval(() => {
this.counter++
}, 1000)
}
})
// 变化2:实例方法
app.component('comp', {
template: '<div>1212</div>'
})
// 变化3: 挂载mount
app.mount('#app')
</script>
查看堆栈信息
对于当前组件,只要有响应式数据发生变化就会重新执行更新函数
再其次内部会调用patch。(我们可以将断点打在patch)
浏览器:comand+p,打开对应文件,回顾前面知识,patch在renderer.ts文件中
comand+f搜索patch,由于是ts类型因此搜索patch:
断点打在switch上
查看对应堆栈
断点调试
我们已经有了整体运行流程的一个概念了,因此接下来我们从运行开始的部分打断点进行单步调试
单步调试下一步是进入PublicInstanceProxyHandlers,这个方法就是响应式机制的方法,vue3.0中使用proxy进行了响应式机制的变更,可以对ste、get进行监听。
接下来会进行trigger运行更新动作,在triggerEffects中进行,其中deps[0]中一定有一个副作用可以被运行。
在effect中,将当前更新元素放入队列,执行queueJob(),这里就是异步更新策略,使用异步的方式调用副作用执行函数。
最终方法会被执行到patch的部分。