Vue3核心运行时之runtime-core

在 Vue3 的源码中,@vue/runtime-core 是整个框架的运行时的核心。它不直接操作DOM,通过@vue/runtime-dom实现vnode的创建、对比与更新。

本文主要基于runtime-core的核心流程,包括组件的初始渲染流程与更新等简要实现机制。

一、runtime-core作用

runtime-core = 平台无关的 VNode 调度器 + 组件生命周期管理
1.对比新旧虚拟 DOM,决定如何更新
2.管理组件实例的创建、渲染与更新

二、从 createApp 到 render

在vue日常开发中,入口文件通常会有这段创建应用实例的代码:

javascript 复制代码
createApp(App).mount('#app')

createApp是vue内部渲染器创建的一个函数,接收一个根组件后进行mount,实现如下:

javascript 复制代码
createRenderer(options) //创建渲染器
// runtime-core 内部
//options 包含runtime-dom平台操作接口(如 insert, createElement, patchProp)等
//返回 { render, createApp }
export function createRenderer(options) {
  return createBaseRenderer(options)
}
export function createBaseRenderer(rendererOptions) { // 渲染时所到的api
    const render = (vnode,container) =>{ // 核心渲染方法
		// 将虚拟节点转化成真实节点插入到容器中.....
    }
    return {
        createApp:createAppAPI(render)
    }
}
//createAppAPI实现
let uid = 0
export function createAppAPI(render) {
    const createApp = (rootComponent, rootProps = null) => {
    const app = {
      _uid: uid++,
      _component: rootComponent,
      _props: rootProps,
      _container: null,
    //   _context: context,
      _instance: null,

      mount(rootContainer){
        const vnode = createVNode(rootComponent, rootProps)
        render(vnode, rootContainer)
        app._container = rootContainer
      }
    }
    return app
}
    return createApp
}




//createApp 返回应用实例
const app = createApp(rootComponent)
app.mount(container)

//mount 最终调用 render(vnode, container)

//render 启动首次渲染
function render(vnode, container) {
  patch(null, vnode, container) // 首次挂载:oldVNode 为 null
}

三、patch 函数

patch(n1, n2, container) 是 runtime-core 实现元素或组件挂载和比对的重要函数

javascript 复制代码
if (n1 === n2) return // 相同节点,跳过

if (n1 && !isSameVNodeType(n1, n2)) {
  // 类型不同:卸载旧节点,挂载新节点
  unmount(n1)
  n1 = null
}
// 根据 n2 类型分发处理
switch (n2.type) {
  case Text: processText(n1, n2, container); break
  case Comment: processCommentNode(...); break
  default:
    if (shapeFlag & ELEMENT) processElement(...)
    else if (shapeFlag & COMPONENT) processComponent(...)
}
//关键思想:  
n1 == null时挂载(mount)  
n1 存在进行更新(update)

四、元素节点和组件处理

javascript 复制代码
//处理元素节点:processElement
挂载:mountElement
创建真实元素:hostCreateElement
设置属性:hostPatchProp
插入容器:hostInsert
更新:patchElement
所有 hostXXX 操作均由 runtime-dom 提供,runtime-core 只调用接口。
javascript 复制代码
//组件节点(processComponent)
//挂载(n1 == null)
mountComponent(n2, container) {
  const instance = createComponentInstance(n2)
  setupComponent(instance)        // 执行 setup()
  setupRenderEffect(instance)     // 创建渲染 effect!
}

//更新(n1 存在):
updateComponent(n1, n2) {
  if (shouldUpdateComponent(n1, n2)) {
    instance.next = n2           // 标记新 vnode
    instance.update()            // 触发 effect 重新执行
  }
}

五、组件自动更新简化实现版

javascript 复制代码
//setupRenderEffect是组件实现自动更新的一个重要函数:

function setupRenderEffect(instance) {
  instance.update = effect(() => {
    if (!instance.isMounted) {
      const subTree = instance.render()
      patch(null, subTree, container)
      instance.isMounted = true
    } else {
      // 更新:render 新子树与旧子树 diff
      const nextTree = instance.render()
      patch(instance.subTree, nextTree, container)
      instance.subTree = nextTree
    }
  }, {
    scheduler: queueJob // 异步更新队列
  })
}

当ref 或 reactive 数据变更时会trigger找到依赖的 effect(即 instance.update),调用scheduler(异步批量更新),effect重新执行后调用render()再进行patch子树

六、总结

runtime-core不直接处理DOM操作,只通过runtime-dom对应方式处理vnode的实现,并贯穿应用实例的创建到卸载整个生命周期流程,本文主要基于runtime-core的核心实现流程,在具体应用包括组件数据渲染,响应式数据更新等一系列流程后续会进行更新。好了,今天就到这里,欢迎有问题的小伙伴一块交流!

相关推荐
2301_32241428042 小时前
基于SpringBoot+Vue的休闲零食超市管理系统的设计与实现59004-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·redis·mysql·决策树·推荐算法
怕浪猫3 小时前
外包和大厂的前端代码,差在凌晨三点
前端·面试·github
m0_敲代码的彭于晏1684 小时前
Vercel 前端部署与全栈开发实战指南
前端·状态模式
徐小夕4 小时前
花了3个月,我们做了一款 AI 版的“飞书文档”
前端·算法·github
贾伟康4 小时前
【化学实验室|17】HarmonyOS ArkTS 亮暗色与视觉令牌实战:集中颜色、间距和交互状态避免页面割裂
前端·移动开发·harmonyos·arkts·arkui
Csvn5 小时前
SSR/SSG/ISR(上):峡谷与渲染策略的时间预算
前端
Csvn5 小时前
SSR/SSG/ISR(下):可交互性、新鲜度与回源账
前端
酷炫码神5 小时前
Day 10|Pinia 状态管理:把散落在各组件的数据,收进一个全局仓库
android·开发语言·javascript
Elcker7 小时前
YnuoAgent(依诺):一个 npm 包,跑起属于自己的 AI 研发平台
前端·人工智能·npm
酷炫码神8 小时前
Day 8|Vue3 响应式:告别手动操作 DOM,让数据驱动界面
javascript·vue.js·ecmascript