Vue 实例详解

目录

  • [一、创建一个 Vue 实例](#一、创建一个 Vue 实例)
    • [1、Vue 2](#1、Vue 2)
    • [2、Vue 3](#2、Vue 3)
  • [二、Vue3:createApp 到 mount 发生了什么?](#二、Vue3:createApp 到 mount 发生了什么?)
  • [三、render 阶段发生了什么?](#三、render 阶段发生了什么?)
  • 四、组件实例是在什么时候创建的?
    • [1、mountComponent 做了什么(核心)](#1、mountComponent 做了什么(核心))
      • [(1)、createComponentInstance ------ 创建"组件实例对象"](#(1)、createComponentInstance —— 创建“组件实例对象”)
      • [(2)、setupComponent ------ 初始化组件内容](#(2)、setupComponent —— 初始化组件内容)
      • [(3)、setupRenderEffect ------ 创建"自动更新机制"](#(3)、setupRenderEffect —— 创建“自动更新机制”)
  • [五、"创建 Vue 实例"本质是创建了什么?](#五、“创建 Vue 实例”本质是创建了什么?)

一、创建一个 Vue 实例

创建 Vue 实例 = 创建一个"组件实例 + 响应式作用域 + 渲染副作用 + 生命周期调度系统"

不是简单 new 个对象,本质上是:

  • 启动一个完整的 UI 运行时系统

1、Vue 2

cpp 复制代码
new Vue({
  el: '#app',
  data() {
    return { count: 0 }
  },
  template: `<button @click="count++">{{ count }}</button>`
})

2、Vue 3

cpp 复制代码
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

看起来只是"启动一下",但实际上 Vue 在背后做了 一整套 UI 引擎初始化工作。

二、Vue3:createApp 到 mount 发生了什么?

我们从 Vue3 开始(现代项目为主)。

1、createApp(App) ------ 创建应用实例

cpp 复制代码
const app = createApp(App)

此时 Vue 做了几件关键事:

做了什么 本质
创建 app 对象 应用级上下文容器
保存根组件 App 作为根 vnode 的来源
初始化依赖注入容器 provide/inject 根级作用域
准备全局配置 directive、component、plugin 注册入口

但注意:这时页面还没开始渲染。

2、app.mount('#app') ------ 真正启动渲染

这一行,才是 Vue 真正"活过来"的地方。

内部核心流程可以简化为:

cpp 复制代码
mount(rootContainer) {
  // 1. 创建根组件的虚拟节点
  const vnode = createVNode(App)

  // 2. 渲染
  render(vnode, rootContainer)
}

三、render 阶段发生了什么?

render() 其实是 Vue 渲染引擎的总入口:

cpp 复制代码
render(vnode, container) {
  patch(null, vnode, container)
}

第一次渲染时 oldVNode 为 null,所以是"挂载"。

四、组件实例是在什么时候创建的?

答案是:在 patch 过程中

当 patch 发现 vnode 是组件:

cpp 复制代码
processComponent(n1, n2, container) {
  mountComponent(n2)
}

1、mountComponent 做了什么(核心)

这是 创建 Vue 实例真正的本质阶段:

cpp 复制代码
function mountComponent(initialVNode, container) {
  // 1.创建组件实例对象
  const instance = createComponentInstance(initialVNode)

  // 2.初始化组件
  setupComponent(instance)

  // 3.建立响应式渲染副作用
  setupRenderEffect(instance, initialVNode, container)
}

我们逐个拆。

(1)、createComponentInstance ------ 创建"组件实例对象"

这一步创建的不是 DOM,而是内存形态:

cpp 复制代码
instance = {
  vnode,              // 当前组件的虚拟节点
  type,               // 组件定义(App)
  props,
  attrs,
  slots,
  ctx,                // 代理上下文(this.xxx 来源)
  setupState,         // setup() 返回的数据
  data,
  isMounted: false,
  subTree: null,      // 组件渲染出的子树
  update: null        // 响应式更新函数
}

👉 这就是 Vue 组件的"内存形态"

(2)、setupComponent ------ 初始化组件内容

这里才真正开始处理你写的代码。

如果是 Options API:

  • 解析 props
  • 执行 data()
  • 绑定 methods
  • 创建 computed
  • 注册 watch
  • 处理生命周期

如果是 Composition API:

cpp 复制代码
const setupResult = setup(props, ctx)

Vue 会把 setup 返回值:

返回类型 处理方式
函数 作为 render 函数
对象 作为组件状态挂到 instance.setupState

此时:

  • 响应式数据创建完
  • 依赖收集系统就绪
  • 生命周期注册完

(3)、setupRenderEffect ------ 创建"自动更新机制"

🔥 这是 Vue 最核心的一步。

Vue 会创建一个响应式副作用:

cpp 复制代码
instance.update = effect(function componentEffect() {
  if (!instance.isMounted) {
    // 首次渲染
    const subTree = instance.render()
    patch(null, subTree, container)
    instance.subTree = subTree
    instance.isMounted = true
  } else {
    // 更新渲染
    const nextTree = instance.render()
    patch(instance.subTree, nextTree, container)
    instance.subTree = nextTree
  }
})

这段代码的意义是:

  • 把组件的 render() 变成一个响应式副作用函数

于是:

当数据变化时 发生什么
响应式依赖触发 effect 重新执行
render() 再次运行 生成新虚拟 DOM
patch diff 更新真实 DOM

这就是 Vue 自动更新的本质。

五、"创建 Vue 实例"本质是创建了什么?

我们总结成 5 个核心系统:

系统 作用
组件实例对象 组件的运行时载体
响应式状态系统 data / setup / props 可追踪
渲染函数 render() 负责生成虚拟 DOM
渲染副作用 effect 自动追踪依赖并触发更新
生命周期调度器 beforeMount、mounted 等时机控制

当你写:

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

Vue 并不是"帮你把 HTML 画出来"这么简单,而是:

cpp 复制代码
1. 创建组件实例
2. 把你的数据变成响应式
3. 把模板变成 render 函数
4. 创建一个 effect 包裹 render
5. effect 自动监听数据变化
6. 数据一变,重新 render + diff + 更新 DOM

也就是说:

  • Vue 实例 = 一个会自己重新执行 render 的智能 UI 机器人
相关推荐
萧曵 丶9 小时前
Vue 中父子组件之间最常用的业务交互场景
javascript·vue.js·交互
Amumu1213810 小时前
Vue3扩展(二)
前端·javascript·vue.js
泓博12 小时前
Android中仿照View selector自定义Compose Button
android·vue.js·elementui
+VX:Fegn089513 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
pas13614 小时前
45-mini-vue 实现代码生成三种联合类型
前端·javascript·vue.js
boooooooom16 小时前
Vue v-for + key 优化封神:吃透就地复用与强制重排,再也不卡帧!
javascript·vue.js·面试
程序猿_极客17 小时前
【2026】分享一套优质的 Php+MySQL的 校园二手交易平台的设计与实现(万字文档+源码+视频讲解)
vue.js·毕业设计·php·mysql数据库·二手交易系统
青屿ovo18 小时前
Vue2跨组件通信方案:全局事件总线与Vuex的灵活结合
前端·vue.js
赵_叶紫19 小时前
使用Cursor 完成 Vike + Vue 3 + Element Plus 管理后台 — 从 0 到 1 (实例与文档)
vue.js
harrain19 小时前
vue全局trycatch
前端·javascript·vue.js·firebug·trycatch