《Vue.js设计与实现》笔记 第12章:组件的实现原理

Vue.js设计与实现 第12章:组件的实现原理

本章导读

前面渲染器处理的是:

{
  type:'div'
}

而组件VNode:

{
  type: MyComponent
}

渲染器需要知道:

如何创建组件

如何执行组件

如何更新组件

本章核心:

组件实例

生命周期

props

setup

render

组件更新

一、组件本质是什么

普通元素

{
  type:'div'
}

表示:

<div></div>

组件

{
  type: Component
}

例如:

const MyComponent = {
  render(){
    return {
      type:'div',
      children:'hello'
    }
  }
}

组件本质:

返回VNode的对象

二、组件渲染流程

整体流程:

组件VNode

↓

创建组件实例

↓

初始化props

↓

执行setup

↓

执行render

↓

生成子树subTree

↓

patch

↓

真实DOM

三、组件实例

为什么需要实例

组件运行期间需要保存:

props

state

slots

生命周期

render函数

因此创建:

instance

结构:

const instance = {

  state:null,

  props:null,

  isMounted:false,

  subTree:null

}

四、创建组件实例

createComponentInstance

实现思想:

function createComponentInstance(
  vnode
){

  const instance = {

    vnode,

    type:vnode.type,

    props:{},

    state:{},

    isMounted:false,

    subTree:null

  }

  return instance
}

作用:

保存组件运行状态

五、初始化Props

父组件

<Child
  title="Vue"
/>

VNode:

{
 props:{
   title:'Vue'
 }
}

组件接收:

props.title

初始化:

instance.props =
 vnode.props

六、区分Props和Attrs

组件定义

props:{
  title:String
}

父组件:

<Child
 title="Vue"
 id="box"
/>

结果:

title

↓

props

id

↓

attrs

七、组件状态state

Options API

data(){

 return {

   count:0

 }

}

执行:

const state =
 reactive(
   data()
 )

结果:

响应式state

保存:

instance.state

八、setup函数

Vue3新增:

setup(props){
}

作用:

组合式API入口

执行时机:

组件创建后

render之前

九、setup返回对象

示例

setup(){

 return {

   count:ref(0)

 }

}

保存:

setupState

结果:

instance.setupState

十、setup返回函数

示例

setup(){

 return ()=>{

   return {
     type:'div'
   }

 }

}

返回:

render函数

组件最终:

render = setupResult

十一、render函数

作用

生成:

VNode树

例如:

render(){

 return {

   type:'div',

   children:'hello'

 }

}

结果:

subTree

十二、组件挂载

执行render

const subTree =
 render.call(...)

得到:

{
 type:'div'
}

然后:

patch(
 null,
 subTree,
 container
)

继续渲染。


十三、组件更新

为什么更新

响应式数据变化:

count.value++

触发:

trigger

重新执行:

render()

生成:

newSubTree

十四、组件更新流程

旧subTree

↓

render()

↓

新subTree

↓

patch()

↓

DOM更新

十五、effect驱动组件

组件更新依赖:

effect(
  componentUpdateFn
)

作用:

自动重新执行render

流程:

state变化

↓

trigger

↓

effect

↓

render

↓

patch

十六、组件首次挂载

判断

instance.isMounted

首次:

false

执行:

mount

然后:

instance.isMounted = true

十七、组件更新

再次执行:

isMounted=true

进入:

update

不再创建DOM。


执行:

patch(
 oldSubTree,
 newSubTree
)

十八、组件生命周期

beforeCreate

创建实例前。


created

实例创建完成。


beforeMount

挂载前。


mounted

挂载完成。


beforeUpdate

更新前。


updated

更新完成。


生命周期执行顺序

beforeCreate

↓

created

↓

beforeMount

↓

mounted

↓

beforeUpdate

↓

updated

十九、renderContext

问题

render中访问:

this.count

实际上来自:

state

props

setupState

解决:

Proxy(instance)

实现统一代理。


读取流程:

this.count

↓

setupState

↓

state

↓

props

二十、组件整体流程

VNode(Component)

↓

createInstance

↓

initProps

↓

initState

↓

setup

↓

render

↓

subTree

↓

patch

↓

DOM

第12章核心知识图谱

Component

│

├── VNode

│

├── Instance

│     ├── props
│     ├── state
│     ├── attrs
│     ├── setupState
│     └── subTree

│

├── setup()

│

├── render()

│

├── effect()

│

└── patch()

高频面试题

Vue组件本质是什么?

返回VNode的对象

什么是组件实例?

保存组件运行时状态。

例如:

props

state

subTree

setup执行时机?

组件创建后

render之前

setup可以返回什么?

对象

或

函数(render)

render函数作用?

生成:

VNode树

组件如何更新?

响应式数据变化

↓

effect

↓

render

↓

patch

subTree是什么?

组件render生成的:

VNode树

为什么需要renderContext?

统一访问:

props

state

setupState

本章总结

组件本质:

一个返回VNode的对象

运行流程:

创建实例

↓

初始化props

↓

初始化state

↓

执行setup

↓

执行render

↓

生成subTree

↓

patch

↓

DOM

组件更新:

state变化

↓

trigger

↓

effect

↓

render

↓

patch

核心概念:

  1. Component VNode
  2. Component Instance
  3. props
  4. state
  5. setup
  6. render
  7. subTree
  8. 生命周期
  9. renderContext

这一章是真正进入 Vue Runtime Core 的开始,也是后续学习组件生命周期、异步组件、KeepAlive、Teleport、Suspense 等高级特性的基础。

posted @ 2025-06-10 09:19  Li_pk  阅读(8)  评论(0)    收藏  举报