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的核心实现流程,在具体应用包括组件数据渲染,响应式数据更新等一系列流程后续会进行更新。好了,今天就到这里,欢迎有问题的小伙伴一块交流!

相关推荐
AugustRed6 小时前
A2UI 完整学习指南(含 Java 后端 + 前端实战示例)
java·开发语言·前端
王莎莎-MinerU6 小时前
Agent 时代,科学数据 API 需要重新设计
大数据·前端·数据库·人工智能·个人开发
jingling5556 小时前
自建技术博客实战(三):工具专栏——地图定位、声音复刻与 rembg 抠图
android·开发语言·前端·ai·nextjs
小小小小宇6 小时前
Chrome 插件在新开页生效
前端
橘子味的冰淇淋~6 小时前
优化前端性能之从“全局引入”改为“按需引入”
前端·javascript·vue.js
沐灵洛6 小时前
构建 Mac App Store 应用须知(全)
前端
KaMeidebaby6 小时前
卡梅德生物技术快报|蛋白修饰调控 NETosis 分子机制及实验研究进展
前端·数据库·人工智能·算法·百度
颜进强7 小时前
Claude Code -16 文件引用与加载机制完整实践:从 CLAUDE.md 到 Skills 与 Subagents
前端·后端·ai编程
2501_940041747 小时前
硬核全栈开发命题,覆盖高并发/实时/微服务
前端
风骏时光牛马7 小时前
Bash变量未加双引号导致文件名含空格解析异常实战案例
前端