Vue 框架整体理解笔记
一、前端框架到底要解决什么?
假设没有 Vue,我们写一个页面:
1 | <div id="temperature"></div> |
JS:
1 | let temperature = 80; |
本质上我们做了三件事:
1 | 数据 |
小页面没问题。
但项目大了,问题就来了:
数据变化以后,到底哪些 DOM 要更新?
如果全部自己管理:
1 | temperature 变了 |
最后大量代码不是在描述业务,而是在:
手动维护“数据和页面之间的同步关系”。
这就是 Vue 最核心的问题背景。
二、Vue 做出的第一个核心设计:声明式 UI
传统思路:
数据变了以后,我告诉浏览器具体怎么修改 DOM。
Vue 希望你变成:
我告诉 Vue:这个页面在当前数据状态下应该长什么样。
例如:
1 | <template> |
你只描述:
1 | 页面 |
然后:
1 | temperature.value = 90; |
Vue 负责:
1 | 发现数据变化 |
所以思想发生了变化:
1 | 以前: |
这就是:
声明式(Declarative)
你负责说:
“页面应该是什么。”
框架负责:
“怎么把页面变成这样。”
三、那么 Vue 怎么知道数据变了?
这就出现 Vue 第二个核心设计:
响应式系统
例如:
1 | const temperature = ref(80); |
页面使用:
1 | <div>{{ temperature }}</div> |
Vue 建立了一个关系:
1 | temperature |
以后:
1 | temperature.value = 90; |
Vue知道:
1 | temperature 发生变化 |
所以响应式系统解决的是:
状态变化以后,谁需要知道?
可以把它理解成:
1 | 状态 |
这其实是一个很通用的软件设计思想。
四、为什么需要 ref / reactive?
因为普通 JavaScript:
1 | let temperature = 80; |
Vue不能凭空知道:
“刚才这个变量变了,我应该更新哪里。”
所以需要把状态纳入 Vue 的响应式体系。
例如:
1 | const temperature = ref(80); |
或者:
1 | const device = reactive({ |
可以粗略理解成 Vue 给数据增加了:
1 | 读取时 |
Vue 3 对响应式对象的重要底层能力就是 JavaScript 的 Proxy。
例如概念上:
1 | const device = new Proxy(data, { |
真实 Vue 实现复杂得多,但思想就是这个。
五、现在出现第三个问题:页面这么大,不能全写一起吧?
于是 Vue 设计了:
组件系统
比如 HMI:
1 | 整个页面 |
每一个都是 Component(组件)。
为什么?
因为大型 UI 天然就是:
1 | 大页面 |
例如:
1 | App |
这样解决:
1 | 代码组织 |
所以:
组件化解决的是“大 UI 怎么拆”。
而:
响应式解决的是“数据变了 UI 怎么跟着变”。
这两个不要混。
六、组件之间怎么交流?
组件拆开以后马上产生新问题:
1 | 父组件 |
数据怎么传?
Vue设计:
1 | 父 → 子 |
为什么这么设计?
因为如果大家:
1 | A 随便修改 B |
项目很快乱掉。
所以 Vue 倾向于建立比较清楚的数据流。
例如:
1 | DevicePage |
子组件如果发生事件:
1 | TemperatureCard |
所以:
1 | 数据向下 |
是一种很重要的组件通信思想。
七、为什么需要 computed?
假设有:
1 | temperature = 105 |
页面还需要:
1 | 是否高温? |
这个状态其实不是独立数据。
因为:
1 | temperature |
所以:
1 | const isHighTemperature = computed(() => { |
为什么 Vue 单独设计 computed?
因为这种东西属于:
派生状态。
它不是新的事实。
事实只有:
1 | temperature = 105 |
而:
1 | isHighTemperature = true |
是从事实算出来的。
所以最好不要:
1 | temperature.value = 105; |
否则以后很容易:
1 | temperature = 80 |
两个状态不一致。
正确思想:
1 | 原始状态 |
一句话
能从已有状态算出来的东西,尽量不要重复保存一份状态。
这是非常重要的软件设计思想。
八、那为什么又需要 watch?
因为有些事情不是“计算一个新值”。
例如:
1 | 设备 ID 变化 |
或者:
1 | 用户修改搜索关键词 |
这叫:
副作用(Side Effect)
比如:
1 | watch(deviceId, async (newId) => { |
所以:
1 | computed |
这两个特别容易混。
记:
1 | computed |
虽然是简化,但面试非常好用。
九、为什么需要生命周期?
一个组件不是永远存在。
例如:
1 | 进入设备详情页 |
于是我们经常需要:
1 | 组件出现的时候 |
所以:
1 | onMounted(() => { |
生命周期解决的是:
组件处于不同生命阶段时,我需要执行什么逻辑?
你可以类比 Node 服务:
1 | 启动 |
组件也是:
1 | 创建 |
十、到这里 Vue 核心已经出来了
其实你现在已经能看到 Vue 的骨架:
1 | Vue |
这才是 Vue 本身最核心的一层。
十一、但是还有一个大问题:Vue 怎么更新 DOM?
比如:
1 | temperature.value = 80; |
变:
1 | temperature.value = 81; |
最笨的方法:
1 | 数据变化 |
当然不行。
所以 Vue 还需要:
渲染系统(Renderer)
你写:
1 | <template> |
Vue 编译器会把模板编译成渲染相关代码。
可以粗略理解:
1 | template |
这里出现一个重要东西:
Virtual DOM,虚拟 DOM。
十二、虚拟 DOM 到底是什么?
不要把它神化。
真实 DOM:
1 | <div> |
Vue内部可以用 JavaScript 对象描述 UI。
概念上:
1 | { |
这类描述就是 VNode。
可以粗略理解:
用 JavaScript 数据结构描述 UI 应该是什么样。
状态变化:
1 | 旧 VNode |
Vue渲染系统判断:
1 | h1 |
于是:
1 | 只更新必要的 DOM |
十三、为什么 Vue 既需要 Compiler 又需要 Renderer?
你写的是:
1 | <template> |
这是人比较容易写的东西。
但是框架最终需要执行:
1 | 创建什么节点 |
所以:
1 | 你写 Template |
职责非常清晰:
1 | Compiler |
十四、为什么 Vue 还需要调度系统?
假设:
1 | temperature.value = 81; |
如果每改一次:
1 | 立即完整更新一次 UI |
可能产生很多没必要的工作。
所以 Vue 会对更新进行调度和批处理。
可以粗略理解:
1 | 状态连续变化 |
这也是为什么你有时候:
1 | count.value++; |
DOM 不一定已经立即完成更新。
于是 Vue 提供:
1 | await nextTick(); |
意思可以理解:
等 Vue 把这一轮 DOM 更新处理完。
十五、Vue Router
注意:
Router 并不是响应式系统的一部分。
它解决另外一个大型应用问题:
1 | URL |
例如:
1 | /dashboard |
所以:
Vue Router = 前端路由管理。
大型单页应用 SPA 才需要这一层。
十六、Pinia 又为什么出现?
组件少的时候:
1 | App |
props 就够了。
但是如果:
1 | App |
很多地方都需要:
1 | 当前用户 |
如果一直:
1 | props |
很麻烦。
于是出现:
全局状态管理。
例如 Pinia:
1 | Pinia Store |
大家读取同一个共享状态。
所以:
1 | ref/reactive |
这个层次就清楚了。
十七、把 Vue 整个框架从上往下看
现在不要看 API。
看架构:
1 | Vue 应用 |
这里面真正属于 Vue 核心的部分,和 Vue Router、Pinia 这种生态配套,要有区分。
十八、为什么 Vue 要设计 Composition API?
以前 Vue 2 常见 Options API:
1 | export default { |
一个业务功能可能被拆散:
1 | 设备 WebSocket 功能: |
同一个功能散在不同配置区域。
Composition API:
1 | function useDeviceSocket() { |
这样:
1 | WebSocket相关 |
而且可以抽:
1 | useDeviceSocket() |
复用逻辑。
所以 Composition API 一个很重要的设计目标就是:
让相关业务逻辑更容易组织在一起,并方便逻辑复用,尤其适合复杂组件。
这也是为什么 Vue 3 项目经常看到:
1 | <script setup> |
十九、不要把 Vue 记成一堆 API
api可能是:
1 | Vue |
这样很容易忘。
改成:
1 | Vue 要解决大型 UI 开发 |
为什么需要这个东西。比记住api更重要
而是在理解:
Vue 是围绕“状态驱动 UI”这个核心,设计出响应式、组件、编译、渲染、调度等机制,再通过 Router、Pinia 等生态能力支撑完整大型前端应用。
一句话记住
Vue 最核心的思想可以先浓缩成:
1 | 状态 |
而:
1 | 组件化 |
负责把复杂页面拆开。

