注释大部分都在代码中,本笔记只是为了理思路
代码仓库: 手敲mini-vue: vue3源码的mini版本,写了特别详细的注释与简单的ts类型,便于自己日后复习 (gitee.com)
1.认识vue3源码结构
上面那半主要是把template转为render函数,其中转换后的js代码会包含很多运行时的函数,就是交给下半部分做,
2.reactivity的核心流程
从下面这个文件开始,ctrl+左键一步步点击查看流程。注释大部分都在代码中!本笔记只是为了理思路
~\reactivity\__tests__\reactive.spec.ts
在 const xx = reactive({}) 的时候,实际上执行了下面的步骤:
执行createReactiveObject函数,在这个函数中,核心就是创建Proxy (这里第二个参数是当前所有reactive数据的集合,有就直接返回了),其中创建Proxy最重要的就是处理器,也就是下图的baseHandelers。
在 baseHandelers 中,主要是进行了下面的操作:
- 在get中进行依赖收集(即effect副作用)
- 递归当前对象,如果属性是对象,也要变成reactive响应式数据(也就是给每个子对象都执行createReactiveObject函数的全部流程,全部都是Proxy对象了。)
然后当响应式数据被改变时,将会触发setter (在 baseHandelers 中定义的)
在trigger函数中,做的事是:拿到当前target对应的依赖Map,然后从Map中拿出对应key的依赖Set,把Set中的所有依赖都取出来,最后交给 triggerEffects 去执行依赖 (实现响应式)
3.runtime-core 初始化的核心流程
总结就是,遇到组件类型的就找render,变成element类型,最后一个个渲染出
在main.js中,会有一句这个代码:
我们打开createApp函数
~\runtime-core\src\createApp.ts
先调用createVNode函数,初始化Vnode节点,然后调用render函数(这里先不看createVNode)
在render函数中,调用了patch函数。在patch函数中,会根据Vnode的shapeFlag,来判断是什么类型(HTML标签还是vue组件,具体判断方法后面会讲),然后调用不同的函数。
如果是组件类型的话:分为两种,这里我们只看初始化
然后经过上面的处理,又回到了patch,然后我们看看挂载element类型时的操作。同样暂时只看初始化挂载部分
如果是简单的children,直接渲染即可(比如文本节点),如果是复杂的,就需要递归调用patch
递归结束后,触发生命周期钩子,挂载前触发beforeMount,然后插入真实dom,然后挂载结束触发Mounted