背景
最近在学习Vue源码,跟Vue2还是有很大的不同的,
这一次主要是看了runtime-dom, runtime-core, reactivity,
reactivity 是另起一篇来讲,下面主要讲runtime-core,
其实主要源码还是在runtime-core 里面的,runtime-dom 里面看看 createApp 和 nodeOps 就好了, createApp的api 还是在core里面的createAppAPI.ts 里面定义的,nodeOps 主要就是封装了DOM原生的一些方法,比如,最经典的inserBefore, 到时候就在 mountElement 挂载元素的时候用到。
初始化流程
跟着代码走
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App);
app.use(store).use(router).mount('#app')
-
createApp(App) // @vue/runtime-dom创建Vue实例,扩展一些方法,比如use, mount, mixin, component, directive; 方法最终的定义位置为runtime-core/src/apiCreateApp.ts -
createRenderer -> baseCreateRenderer() 对外暴露三个方法,render、hydrate、createApp; hydrate的实际作用是createApp返回的vue实例对象,这里的render就是最重要的那个render函数了,render.ts,以函数名命名的文件;
-
createAppAPI(render, hydrate); 返回createApp() 并且扩展了一些实例方法,链式调用
-
mount(rootContainer: HostElement, isHydrate?: boolean) 作用, 把传入的根组件转化为VNode,然后挂载到rootContainer 中
-
render(vnode, container) 作用: 将VNode渲染到容器container上
-
patch(n1, n2, container);n1 一开始是空的,根据n2的类型执行不同的函数,如果是组件,就会执行 processComponent
-
processComponent(n1, n2, container); 执行组件的挂载或者更新, 因为n1一开始是空,所以直接执行挂载 mountComponent
-
mountComponent(initialVNode, container); 创建组件实例 createComponentInstance ,设置数据状态 setupComponent
-
setupComponent(); 位于component.ts
-
setupStatefulComponent() 调用 callWithErrorHandling,也就是 调用setup 函数
-
callWithErrorHandling() 调用setup() 传入两个参数 props 和 setupContext
-
handleSetupResult(instance, setupResult, isSSR); 处理setup 函数返回的对象
目录模块
compile: 可以简单理解为将.vue 文件编译为 浏览器能识别的.js 文件 runtime: 可以理解成,程序运行时,就是程序被编译完成后,在浏览器打开,运行代码,直到程序关闭
- runtime-dom 运行时dom 关api,属性,事件处理
- runtime-core 运行时核心实例相关代码(平台无关)
- shared 内部工具库
- compiler-core
- compiler-dom
- reactivity 响应式模块,可以与任何框架配合使用
- compiler-sfc Vue单文件组件编译工具
- vue 完整源码产生目录
vue.global.js:是包含编译器和运行时的“完整”构建版本,因此它支持动态编译模板 vue.runtime.global.js:只包含运行时,并且需要在构建步骤期间预编译模板
最后,我就不贴源码注释了, 可以参考这个 vue-next-fork