Vue3 源码 -- runtime部分

2,893 阅读2分钟

背景

最近在学习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')
  1. createApp(App) // @vue/runtime-dom 创建Vue实例,扩展一些方法,比如use, mount, mixin, component, directive; 方法最终的定义位置为 runtime-core/src/apiCreateApp.ts

  2. createRenderer -> baseCreateRenderer() 对外暴露三个方法,render、hydrate、createApp; hydrate的实际作用是createApp返回的vue实例对象,这里的render就是最重要的那个render函数了,render.ts,以函数名命名的文件;

  3. createAppAPI(render, hydrate); 返回createApp() 并且扩展了一些实例方法,链式调用

  4. mount(rootContainer: HostElement, isHydrate?: boolean) 作用, 把传入的根组件转化为VNode,然后挂载到rootContainer 中

  5. render(vnode, container) 作用: 将VNode渲染到容器container上

  6. patch(n1, n2, container);n1 一开始是空的,根据n2的类型执行不同的函数,如果是组件,就会执行 processComponent

  7. processComponent(n1, n2, container); 执行组件的挂载或者更新, 因为n1一开始是空,所以直接执行挂载 mountComponent

  8. mountComponent(initialVNode, container); 创建组件实例 createComponentInstance ,设置数据状态 setupComponent

  9. setupComponent(); 位于component.ts

  10. setupStatefulComponent() 调用 callWithErrorHandling,也就是 调用setup 函数

  11. callWithErrorHandling() 调用setup() 传入两个参数 props 和 setupContext

  12. 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