《Vue.js设计与实现》笔记 第3章:Vue.js 3 的设计思路

Vue.js设计与实现 第三章:Vue.js 3 的设计思路

本章导读

Vue3 的核心可以拆分为三大模块:

Vue3

├── 响应式系统(Reactivity)
├── 渲染器(Renderer)
└── 编译器(Compiler)

其中:

  • 响应式系统负责数据变化检测
  • 渲染器负责更新视图
  • 编译器负责优化模板

本章主要介绍:

  • Vue3整体工作流程
  • 响应式系统原理
  • 渲染器工作原理
  • 编译器优化思想

一、声明式描述UI

Vue属于声明式框架。

开发者只需要描述:

<div>Hello Vue</div>

或者:

<div>{{ msg }}</div>

而不需要:

document.createElement()
appendChild()
setAttribute()

声明式的优势

例如:

命令式:

const div = document.createElement('div')
div.innerText = 'Hello Vue'
document.body.appendChild(div)

声明式:

<div>Hello Vue</div>

对比:

命令式 声明式
关注过程 关注结果
代码量大 代码量少
灵活性高 可维护性高
开发效率低 开发效率高

二、渲染器(Renderer)

什么是渲染器

渲染器的职责:

将虚拟DOM转换为真实渲染目标

例如:

VNode
 ↓
Renderer
 ↓
DOM

渲染器并不一定渲染DOM

Vue3设计目标:

跨平台

因此:

VNode
 ↓
Renderer
 ├── 浏览器DOM
 ├── SSR字符串
 ├── 小程序
 └── Native

自定义渲染器

Vue提供:

createRenderer()

允许开发者实现:

  • Canvas渲染器
  • WebGL渲染器
  • 小程序渲染器

渲染器核心能力

挂载(Mount)

初次创建DOM

更新(Patch)

比较新旧VNode
更新变化部分

卸载(Unmount)

移除DOM

渲染流程

VNode
 ↓
Mount
 ↓
DOM

数据变化

VNode
 ↓
Patch
 ↓
更新DOM

三、虚拟DOM

什么是VNode

VNode:

Virtual Node
虚拟节点

本质:

const vnode = {
  type: 'div',
  props: {
    id: 'app'
  },
  children: 'Hello Vue'
}

为什么需要VNode

目的:

统一描述UI

这样:

组件
HTML
SVG
Fragment

都能用统一结构表示。


VNode优势

跨平台

同一个VNode
可以渲染到不同平台

更新优化

通过Diff算法:

比较VNode
更新真实DOM

四、响应式系统

什么是响应式

核心思想:

数据变化
自动更新视图

例如:

state.count++

界面自动刷新。


响应式示例

普通对象:

const obj = {
  text: 'hello'
}

修改:

obj.text = 'world'

页面不会更新。


Vue响应式:

const obj = reactive({
  text: 'hello'
})

修改:

obj.text = 'world'

页面自动更新。


五、副作用函数(Effect)

什么是副作用

副作用:

函数执行会产生额外影响

例如:

document.title = 'Vue'

修改页面标题。


Effect概念

例如:

effect(() => {
  document.body.innerText = obj.text
})

作用:

依赖数据变化
自动重新执行

工作流程

effect执行
 ↓
读取响应式数据
 ↓
收集依赖

数据变化
 ↓
触发effect
 ↓
重新执行

六、依赖收集

为什么需要依赖收集

例如:

effect(() => {
  console.log(obj.text)
})

Vue需要知道:

哪个effect依赖了obj.text

否则无法触发更新。


收集过程

读取属性
 ↓
track()
 ↓
建立依赖关系

例如:

obj.text
   ↓
effect

建立映射。


七、触发更新

数据修改

例如:

obj.text = 'Vue3'

执行:

trigger()

更新流程

set操作
 ↓
trigger()
 ↓
找到依赖
 ↓
执行effect

整体流程

读取数据
 ↓
track()

修改数据
 ↓
trigger()

重新执行effect

八、Vue3为何使用Proxy

Vue2的问题

Vue2使用:

Object.defineProperty()

存在限制:

无法监听新增属性

obj.newProp = 123

无法监听。


无法监听删除属性

delete obj.foo

无法监听。


无法监听数组长度变化

arr.length = 0

存在问题。


Vue3解决方案

使用:

Proxy

例如:

const obj = new Proxy(data,{
  get(){},
  set(){}
})

Proxy优势

监听新增属性

obj.foo = 1

可以监听。


监听删除属性

delete obj.foo

可以监听。


监听数组变化

arr.push()

可以监听。


监听Map和Set

map.set()
set.add()

都能监听。


九、编译器(Compiler)

什么是编译器

作用:

Template
 ↓
Render Function

示例

模板:

<div>{{ msg }}</div>

编译后:

render() {
  return h('div', msg)
}

编译器作用

提升开发体验

开发者写:

Template

即可。


提升运行性能

编译阶段提前分析。


十、编译优化

Patch Flag

标记动态内容:

PatchFlags.TEXT

表示:

只有文本会变化

Static Hoist

静态提升:

<span>静态节点</span>

只创建一次。


Block Tree

收集动态节点:

更新时
直接访问动态节点

减少Diff范围。


十一、Vue3整体工作流程

首次渲染

Template
 ↓
Compiler
 ↓
Render Function
 ↓
VNode
 ↓
Renderer
 ↓
DOM

数据更新

修改数据
 ↓
Proxy拦截
 ↓
trigger()
 ↓
effect重新执行
 ↓
生成新VNode
 ↓
Patch
 ↓
更新DOM

Vue3核心架构图

                Template
                    │
                    ▼
              Compiler
                    │
                    ▼
           Render Function
                    │
                    ▼
                VNode
                    │
                    ▼
              Renderer
                    │
                    ▼
                  DOM


Reactive Data
      │
      ▼
   Proxy
      │
      ▼
 track / trigger
      │
      ▼
   effect
      │
      ▼
重新执行Render
      │
      ▼
更新DOM

高频面试题

Vue3由哪些核心模块组成?

Reactivity
Renderer
Compiler

Renderer作用是什么?

负责:

VNode → 渲染目标

包括:

  • Mount
  • Patch
  • Unmount

什么是VNode?

使用JavaScript对象描述UI结构。


什么是响应式?

数据变化自动触发更新。


effect的作用是什么?

注册副作用函数。

数据变化时自动重新执行。


track和trigger分别做什么?

track
收集依赖

trigger
触发依赖

Vue3为什么使用Proxy?

解决Vue2:

新增属性监听
删除属性监听
数组监听
Map监听

等问题。


编译器的作用是什么?

Template
 ↓
Render Function

同时完成编译优化。


第三章核心知识图谱

Vue3架构

├── Reactivity
│    ├── Proxy
│    ├── effect
│    ├── track
│    └── trigger
│
├── Renderer
│    ├── Mount
│    ├── Patch
│    └── Unmount
│
├── VNode
│
├── Compiler
│    ├── Template
│    ├── Render Function
│    ├── Patch Flag
│    ├── Static Hoist
│    └── Block Tree
│
└── 数据驱动视图

本章总结

Vue3整体由三大核心模块组成:

Compiler
Renderer
Reactivity

工作流程:

Template
 ↓
Compiler
 ↓
Render Function
 ↓
VNode
 ↓
Renderer
 ↓
DOM

响应式更新流程:

Proxy
 ↓
track
 ↓
trigger
 ↓
effect
 ↓
重新渲染

Vue3通过:

  • Proxy
  • VNode
  • Renderer
  • Compiler

构建出完整的:

数据驱动视图系统

第三章实际上是后续源码章节的总纲。

后面第4~6章会正式开始实现:

  1. 响应式系统(effect、track、trigger)
  2. Proxy代理对象
  3. 调度执行机制

这些内容是整本书最重要的部分,也是 Vue 面试和源码学习的核心。

posted @ 2025-02-25 17:08  Li_pk  阅读(3)  评论(0)    收藏  举报