> ## Documentation Index
> Fetch the complete documentation index at: https://opc-43d279b8.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Vue vs React 架构对比

> 从响应式、diff、状态管理与组件模型四个维度做机制对比，不评优劣，只讲各自取舍。

> Vue 和 React 的对比我补过好几次：先比模板和 JSX，后来比响应式和调度，最后才落到两边各自的设计取舍上。

***

## Q1: Vue 和 React 的设计理念有什么本质区别？

**1. React 的理念: JavaScript 驱动一切**

React 的核心哲学是"UI = f(state)"--UI 是状态的函数。它把 HTML、CSS、JavaScript 全部交给 JavaScript 管理（JSX），模板就是 JavaScript 表达式。React 本体只提供核心能力，路由、状态管理、CSS 方案多由社区或上层框架提供（官方文档会推荐 Next.js 等框架）。

**2. Vue 的理念: 渐进式增强**

Vue 的核心哲学是"渐进式框架"--你可以只用核心库，也可以逐步引入路由、状态管理、构建工具。Vue 提供官方推荐的完整方案（Vue Router、Pinia、Vite），模板是增强的 HTML（指令、插槽）。Vue 追求"开箱即用"，降低开发者的心智负担。

**3. 设计哲学的根本分歧**

React 说："我给你自由，你自己选。" Vue 说："我给你推荐，你跟着走。" React 的灵活性是优势也是负担--你需要做更多技术决策。Vue 的完整性是优势也是限制--你被绑在 Vue 的生态里。

**4. 响应式机制的本质差异**

Vue 采用**基于 Proxy 的响应式追踪**--组件渲染时访问了哪些响应式数据，被自动收集为依赖，数据变化时只重新执行依赖它的组件。React 采用**基于 setState 的组件重新渲染**--状态变化后该组件及其子组件重新执行，再通过协调（reconciliation）找出差异。两种机制各有取舍：Vue 默认不需要手工优化，React 的心智模型更直接。

**5. 关键启示：选型取决于团队和项目，而非技术优劣**

面试中回答"Vue vs React"时，千万不要说"哪个更好"--这是陷阱题。正确的思路是：React 适合需要高度灵活、技术决策能力强的团队；Vue 适合需要快速上手、统一技术栈的团队。真正的高级工程师不是选"最好的框架"，而是根据项目需求和团队能力做出最合适的选择。

**设计理念解决的核心问题：**

```text theme={null}
问题：前端框架应该"提供完整方案"还是"只提供核心能力"？

React 的选择：只提供核心能力（React + ReactDOM），路由/状态管理/样式方案全部交给社区
→ 优势：灵活、生态丰富、可以自由组合
→ 劣势：技术决策多、新手容易迷失

Vue 的选择：提供完整方案（Vue + Vue Router + Pinia + Vite），官方推荐最佳实践
→ 优势：开箱即用、学习曲线低、团队统一
→ 劣势：灵活性低、被绑在 Vue 生态
```

> [!NOTE]
>
> React 是"自由市场"，Vue 是"计划经济"--没有绝对的好坏，取决于团队规模和项目复杂度。

> [card] React 的自由选择
>
> React 只提供核心能力，路由/状态管理/CSS 方案全部交给社区。就像去一个没有菜单的餐厅--你可以点任何菜，但你得自己决定吃什么，新手容易选择困难。

> [card] Vue 的官方推荐
>
> Vue 提供完整方案，官方推荐 Vue Router、Pinia、Vite。就像去一个有套餐的餐厅--厨师已经帮你搭配好了，你只需要选套餐 A 还是套餐 B。

> [!TIP]
>
> 回答时不要说"Vue 更好'或"React 更好"--这是陷阱题。应该说"取决于团队规模和项目复杂度"，然后给出具体场景的选型建议。

***

## Q2: 响应式机制有什么本质区别？

### 两种响应式模型

Vue 和 React 的响应式机制是两者最核心的差异之一。

```text theme={null}
┌───────────────────────────────────────┐
│        Vue 的响应式：自动追踪           │
│  Proxy 拦截属性访问 → track 收集依赖   │
│  属性变化 → trigger 精确更新           │
│  组件只更新依赖了该属性的部分           │
└───────────────────────────────────────┘

┌───────────────────────────────────────┐
│        React 的响应式：手动声明         │
│  useState/useReducer 声明状态         │
│  setState 触发整个组件重新渲染         │
│  需要 useMemo/useCallback 手动优化    │
└───────────────────────────────────────┘
```

| 对比维度 | Vue | React |
| - | - | - |
| **响应式原理** | Proxy 自动追踪依赖 | setState 触发组件重新渲染 |
| **更新粒度** | 追踪到属性，更新到组件 | 组件级（子树默认一并执行） |
| **手动优化** | 多数场景不需要 | 常用 useMemo/useCallback |
| **心智模型** | "改了数据，视图自动更新" | "改了数据，重新渲染组件及子树" |
| **性能开销** | Proxy 的 get/set trap | 重渲染 + diff |

> [!WARNING]
>
> 表面上：Vue 的自动追踪省去了手动声明依赖，常规场景下不需要额外优化。
> 反面：Proxy 有运行时开销（每次属性访问都经过 trap），React 的直接函数调用更轻量。Vue 的依赖收集也要维护三层结构（WeakMap → Map → Set），有额外内存成本。
> 判断：中小型应用里 Vue 的响应式更省心；大型应用里 React 的手动优化给了开发者更明确的控制点。
> 升华：Vue 是"框架帮你优化"，React 是"你来优化"--两种取舍，适合的场景不同。

> [!TIP]
>
> Vue 的响应式就像自动驾驶--你踩油门（改数据），车自动开（视图自动更新）。React 的响应式就像手动挡--你踩油门（setState），还得自己换挡（useMemo/useCallback 优化）。自动驾驶更省心，但老司机更喜欢手动挡的控制感。

***

## Q3: Diff 算法有什么区别？

### 基础梳理

| 对比维度 | Vue 2 | Vue 3 | React |
| - | - | - | - |
| **遍历方式** | 双端比较（4 个指针） | 前后缀同步 + 中间乱序 LIS | 单次遍历 + map 定位（lastPlacedIndex） |
| **编译优化** | 静态子树标记 | PatchFlag + Block Tree + 静态提升 | 运行时协调 + React Compiler |
| **时间复杂度** | O(n) | O(n) | O(n) |
| **key 的作用** | 标识节点复用 | 标识节点复用 | 标识节点复用 |
| **静态节点处理** | 静态子树可跳过 | 编译时跳过 | 每次 re-render 重新创建元素 |

### 专家视角深度剖析

### 为什么 Vue 和 React 选择不同的 Diff 策略

很多人能背出"Vue 用双端比较，React 用单向遍历"，但说不清**为什么这样设计**。

React 选择"单次遍历 + map 定位"的原因：React 的设计理念是"UI = f(state)"，每次状态变化都重新执行组件函数。协调阶段一次遍历即可处理常见场景，配合 Fiber 架构的时间切片，可以把渲染拆成多个小块执行，不阻塞主线程。React 把优化的重担交给开发者（useMemo/useCallback/React.memo）。

Vue 3 采用"前后缀同步 + 中间乱序 LIS"的原因：Vue 的响应式系统精确知道哪些组件依赖发生了变化，diff 只需处理这些组件；编译器的 PatchFlag、Block Tree、静态提升再把范围收窄到动态节点。Vue 把优化的重担交给框架。

```javascript theme={null}
// Vue 3：编译器标记动态节点，diff 只比较标记的部分
createElementVNode("div", null, [
  _createElementVNode("span", null, "静态"), // 静态提升，跳过
  _createElementVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */),
]);

// React：没有编译期标记，协调时逐个比较元素与 props
h("div", [
  h("span", "静态"), // 仍会参与协调
  h("span", msg), // 仍会参与协调
]);
// 核心差异：Vue 是"编译时优化"，React 是"运行时优化 + 调度"
```

***

## Q4: 状态管理有什么区别？

### 基础梳理

| 对比维度 | Vue（Pinia） | React（Redux/Zustand） |
| - | - | - |
| **官方推荐** | Pinia | 无统一推荐（Redux/Zustand 常见） |
| **设计理念** | 基于 Vue 的响应式系统 | 独立的状态容器 |
| **API 复杂度** | 简单（state + getters + actions） | Redux 较复杂（reducer + action + dispatch） |
| **TypeScript** | 完美支持 | Redux 需额外配置，Zustand 较好 |
| **DevTools** | Vue DevTools 内置支持 | Redux DevTools（需安装） |
| **体积** | \~1.5KB | Redux \~2KB，Zustand \~1KB |

### 专家视角深度剖析

### 为什么 React 需要外部状态管理

很多人知道"Vue 用 Pinia，React 用 Redux"，但说不清**为什么 React 需要外部状态管理而 Vue 不太需要**。

原因是 Vue 的响应式系统本身就是"状态管理"--你可以在任何组件外创建 `reactive` 对象，所有引用它的组件都会自动更新。Pinia 只是把这个能力包装了一下（加了 DevTools、插件、SSR 支持）。

React 的 `useState` 是组件级别的--状态绑定在组件实例上，组件卸载时状态消失。如果要在多个组件间共享状态，通常用 Context（value 变化会通知所有消费者）或外部状态管理库（Redux/Zustand）。

```javascript theme={null}
// Vue：响应式系统本身就是状态管理
// store.js
export const count = ref(0); // 全局状态，任何组件都能用

// 组件 A
import { count } from "./store";
// 直接用，自动响应

// React：共享状态通常借助外部库（或 Context）
// store.js
import { create } from "zustand";
export const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}));

// 组件 A
import { useStore } from "./store";
const count = useStore((state) => state.count); // 必须通过 hook 访问
```

> [!WARNING]
>
> 表面上：Vue 的响应式系统本身就能共享状态，不一定需要额外的库。
> 反面：在大型应用中，Pinia 还提供了 DevTools 支持、插件系统、SSR 支持、模块化组织等能力，这些是裸 `ref`/`reactive` 不具备的。
> 判断：小型项目用 `ref`/`reactive` 足够；中大型项目引入 Pinia 更好维护。
> 升华：Vue 可以让状态脱离组件存在，但工程化能力仍需要 Pinia 这类库补齐。

***

## Q5: 组件模型有什么区别？

| 对比维度 | Vue | React |
| - | - | - |
| **定义方式** | SFC（单文件组件）+ Composition API | 函数组件 + Hooks |
| **模板语法** | 模板（增强的 HTML）或 JSX | 只有 JSX |
| **双向绑定** | `v-model` 原生支持 | 需手动实现受控组件 |
| **生命周期** | `onMounted`/`onUnmounted` 等独立钩子 | `useEffect` 统一处理 |
| **逻辑复用** | Composables | Hooks |
| **条件渲染** | `v-if`/`v-show` | `{condition && <Comp />}` |
| **列表渲染** | `v-for` | `.map()` |

> [!WARNING]
>
> 表面上：模板更接近 HTML，编译器可以做更多静态优化（PatchFlag、静态提升）。
> 反面：JSX 就是 JavaScript 表达式，条件、循环、高阶函数都能直接表达；模板的编译优化收益随场景变化，不是所有页面都能体现。
> 判断：模板适合结构清晰、描述式的 UI；JSX 适合高度动态、以函数组合为主的 UI。
> 升华：Vue 3 同时支持模板和 JSX，React 只有 JSX——这是两种不同的取舍。

***

## Q6: 数据流有什么区别？

| 对比维度 | Vue | React |
| - | - | - |
| **单向数据流** | ✅ 支持（props 向下，emit 向上） | ✅ 强制（只有 props 向下） |
| **双向绑定** | ✅ `v-model` 原生支持 | ❌ 需手动实现 |
| **状态提升** | 通过 Pinia 或 provide/inject | 通过 Context 或 Redux |
| **副作用管理** | `watch`/`watchEffect` | `useEffect` |

> [!WARNING]
>
> 表面上：双向绑定更方便--`v-model` 一行代码搞定表单双向同步。
> 反面：双向绑定让数据来源不如单向流直观。React 强制单向数据流，数据从父组件流向子组件，子组件通过回调通知父组件修改，数据流向更明确。
> 判断：简单表单场景，双向绑定更方便；复杂应用中，单向数据流更容易追踪。
> 升华：Vue 3 组件上的 `v-model` 本质是"单向数据流 + 语法糖"--编译为 `modelValue` prop + `update:modelValue` 事件，运行时依然是"数据向下、事件向上"。

***

## Q7: 生态对比

| 维度 | Vue | React |
| - | - | - |
| **路由** | Vue Router（官方） | React Router（社区） |
| **状态管理** | Pinia（官方） | Redux/Zustand/MobX（社区） |
| **构建工具** | Vite（官方推荐） | Vite / Next.js |
| **SSR 框架** | Nuxt | Next.js |
| **移动端** | uni-app / Capacitor | React Native |
| **UI 库** | Element Plus / Ant Design Vue | Ant Design / MUI |
| **TypeScript** | 原生支持（Vue 3） | 原生支持 |
| **社区规模** | 小于 React，但活跃 | 更大 |

> [!WARNING]
>
> 表面上：React 的 npm 下载量和社区规模更大，第三方库也更多。
> 反面：Vue 的官方生态更集中--Vue Router、Pinia、Vite 由官方维护，版本同步、文档风格统一。React 的社区生态更丰富，可选方案也更多，需要团队自行做技术选型。
> 判断：需要更多选择和更广的生态选 React，需要开箱即用和统一方案选 Vue。
> 升华：生态规模大，意味着可选方案多；官方生态集中，意味着决策成本低。两者对应不同的团队需求。

***

> [!NOTE]
>
> 虚拟 DOM 是否比原生 DOM 快的详细分析（包括快在哪里、慢在哪里、为什么不直接干掉虚拟 DOM），详见 [Vue Diff](https://opc-43d279b8.mintlify.site/vue/vue-diff.md)。

***

## Q8: Vue 和 React 的虚拟 DOM 实现有什么区别？

### Vue 的编译时优化

Vue 3 的虚拟 DOM 实现引入了大量编译时优化，减少了运行时 diff 的工作量：

```javascript theme={null}
// Vue 3：编译器标记动态节点
// 模板：<div><span>静态</span><span>{{ msg }}</span></div>
// 编译后：
createElementVNode("div", null, [
  // 静态节点——静态提升，只创建一次
  _createElementVNode("span", null, "静态"),
  // 动态节点——PatchFlag 标记，diff 只比较文本
  _createElementVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */),
]);

// PatchFlag 告诉 diff 算法：这个节点只有文本会变，不需要比较其他属性
```

### React 的运行时优化

React 的优化主要发生在运行时（React Compiler 会在编译期补充自动记忆化），协调阶段仍要逐个比较元素与 props：

```javascript theme={null}
// React：协调阶段逐个比较元素与 props
h("div", [
  h("span", "静态"), // 仍会参与协调
  h("span", msg), // 仍会参与协调
]);

// React 的优化主要靠运行时机制：React.memo、useMemo、useCallback
```

### Vue 3 的三层编译优化

| 优化技术 | 说明 | 效果 |
| - | - | - |
| **PatchFlag** | 标记动态绑定的类型（文本、class、style 等） | diff 只比较标记的属性 |
| **Block Tree** | 将动态节点扁平化收集到数组中 | diff 只遍历动态节点，跳过静态子树 |
| **静态提升** | 静态节点只创建一次，后续复用 | 减少对象创建和 GC 压力 |

```text theme={null}
Vue 3 vs React 的 diff 工作量对比（示意）：

假设：一个组件有大量静态节点，只有少数动态节点

Vue 3：
  Block Tree 收集 → 重渲染只遍历动态节点
  PatchFlag 标记 → 每个动态节点只比较对应类型的属性

React：
  从状态变化的组件开始重新执行组件函数，生成新的元素树
  默认逐层比较元素与 props，需要 memo/useMemo 才能跳过稳定子树

结论：静态节点占比越高，Vue 3 的编译优化越能减少运行时比较；
动态节点占比高或结构频繁变化时，两者的实际差距会缩小。
```

> [!WARNING]
>
> Vue 3 通过编译期优化收窄 diff 范围，React 则用 Fiber 时间切片把渲染拆成多个小块执行，不阻塞主线程。Vue 3 的 diff 是同步的，一旦开始就必须执行完。小型组件的更新中，Vue 3 的编译优化收益更直接；超大型组件树中，React 的时间切片有助于保持交互响应。

***

## 底层源码：React 和 Vue 的渲染机制有什么区别？

React 和 Vue 的渲染触发机制有什么区别？

**Vue 的渲染触发**：响应式数据变化时，`trigger` 函数通知所有依赖该数据的 `ReactiveEffect`。每个组件的渲染函数就是一个 `ReactiveEffect`，只有依赖了变化数据的组件才会重新渲染。详见 [Vue 3 源码 packages/reactivity/src/effect.ts](https://github.com/vuejs/core/blob/main/packages/reactivity/src/effect.ts)。

```javascript theme={null}
// Vue：精确更新--只有依赖了 count 的组件才重新渲染
const count = ref(0);
// 组件 A 用了 count → 触发更新
// 组件 B 没用 count → 不触发更新
```

**React 的渲染触发**：`setState` 会把更新调度到对应的 Fiber 节点（`scheduleUpdateOnFiber`），默认重新渲染该组件及其子树；`React.memo`、`useMemo`、`shouldComponentUpdate` 等机制可以让稳定的子树跳过。详见 [React 源码 packages/react-reconciler/src/ReactFiberWorkLoop.js](https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberWorkLoop.js)。

```javascript theme={null}
// React：setState 触发该组件及其子树重新渲染
const [count, setCount] = useState(0);
// 组件 A 用了 count → 触发更新
// 组件 B 是 A 的子组件且未 memo → 也会重新渲染
```

React Compiler 和 Vue 的编译优化有什么相似之处？

React Compiler（原名 React Forget）在编译时自动做记忆化（memoization），把可以复用的计算结果与元素缓存起来，减少不必要的重算与 re-render。它和 Vue 3 的编译器优化（PatchFlag、Block Tree、静态提升）思路相近--**都是把一部分运行时工作提前到编译时**。差别在于优化时机与信息来源：Vue 从设计之初就依赖模板编译，React Compiler 是在既有运行时模型之上补充的编译期优化。

***

## 十、及格回答 vs 满分回答

### 问题："Vue 和 React 的核心区别是什么？"

**及格回答（60-70分）：**

> "Vue 用模板，React 用 JSX。Vue 有双向绑定，React 只有单向数据流。Vue 用 Proxy，React 用 setState。"

问题出在：**背区别但不理解设计**。

**满分回答（90-100分）：**

> Vue 和 React 的核心区别不在 API 层面，而在**设计理念**。React 的哲学是"JavaScript 驱动一切"--它只提供核心能力（React + ReactDOM），把选择权交给开发者。Vue 的哲学是"渐进式增强"--它提供完整方案（Vue Router + Pinia + Vite），降低开发者的心智负担。<sup>\[1]</sup>

> 在**响应式机制**上，Vue 用 Proxy 自动追踪依赖，数据变化时只重新执行依赖了该数据的组件。React 用 setState 触发该组件及其子树重新渲染，常用 useMemo/useCallback 控制跳过范围。Vue 的方式默认更省心，但 Proxy 有运行时开销；React 的方式更直接，把优化控制权交给开发者。<sup>\[2]</sup>

> 在**Diff 算法**上，Vue 3 的编译器做了 PatchFlag、Block Tree、静态提升三层优化，让运行时 diff 只处理动态节点。React 的优化主要在运行时，依靠协调算法与 Fiber 时间切片把渲染拆成多个小块执行；React Compiler 又补上了编译期自动记忆化，思路和 Vue 有相似之处。<sup>\[3]</sup>

> 技术选型的建议：**中小团队、快速迭代、中后台项目选 Vue**（开箱即用、学习曲线低）。**大型团队、复杂应用、跨端需求选 React**（生态丰富、React Native、灵活度高）。没有绝对的好坏，只有适合不适合。

### 常见追问

> [accordion] Vue 的响应式和 React 的 setState 有什么本质区别?
>
> **答题要点：** Vue 是自动追踪依赖，React 是手动声明依赖。
>
> **高分回答：**
> "Vue 的响应式是**自动追踪**--组件渲染时访问了哪些响应式数据，Proxy 的 get trap 自动收集依赖，数据变化时精确到依赖它的组件。React 的 setState 是**显式触发**--开发者通过 useState 声明状态，setState 触发该组件及其子树重新渲染，常用 React.memo/useMemo 控制跳过范围。
>
> ```javascript theme={null}
> // Vue：自动追踪，只有用了 count 的组件才更新
> const count = ref(0);
> // 组件 A 用了 count → 自动更新
> // 组件 B 没用 count → 不更新
>
> // React：手动声明，该组件及其子树重新渲染
> const [count, setCount] = useState(0);
> // 组件 A 用了 count → 重新渲染
> // 组件 B 是子组件且未 memo → 也会重新渲染
> ```
>
> "

> [accordion] 为什么 React 需要外部状态管理 (Redux) , 而 Vue 不太需要?
>
> **答题要点：** Vue 的响应式系统本身就是状态管理，React 的 useState 是组件级别的。
>
> **高分回答：**
> "Vue 的响应式系统本身就是'状态管理'--你可以在组件外创建 `ref`/`reactive` 对象，所有引用它的组件都会自动更新。Pinia 只是把这个能力包装了一下（加了 DevTools、插件、SSR 支持）。
> React 的 useState 是组件级别的--状态绑定在组件实例上，组件卸载时状态消失。如果要在多个组件间共享状态，通常用 Context（value 变化时所有 Consumer 都会 re-render）或外部状态管理库（Redux/Zustand）。
>
> ```javascript theme={null}
> // Vue：组件外创建 ref，任何组件都能用
> export const count = ref(0);
>
> // React：共享状态通常借助外部库（或 Context）
> import { create } from "zustand";
> export const useStore = create((set) => ({ count: 0 }));
> ```
>
> "

> [accordion] Vue 和 React 的 Diff 算法有什么区别?
>
> **答题要点：** Vue 做编译时优化，React 做运行时优化。
>
> **高分回答：**
> "Vue 3 的编译器在编译时做了 PatchFlag（标记动态绑定）、Block Tree（扁平化动态节点）、静态提升（静态节点只创建一次），让运行时 diff 只处理动态节点。React 的优化主要在运行时：依靠协调算法逐层比较，并用 Fiber 的时间切片把渲染拆成多个小块执行，每块执行后检查是否需要让出主线程。
>
> ```javascript theme={null}
> // Vue 3：编译器标记，diff 只比较标记的部分
> createElementVNode("div", null, [
>   _createElementVNode("span", null, "静态"), // 静态提升，跳过
>   _createElementVNode("span", null, msg, 1 /* TEXT */), // 只比较文本
> ]);
>
> // React：协调阶段逐个比较元素与 props
> h("div", [
>   h("span", "静态"), // 仍会参与协调
>   h("span", msg), // 仍会参与协调
> ]);
> ```
>
> "

> [accordion] 你会怎么选 Vue 和 React?
>
> **答题要点：** 这是陷阱题--不能说"Vue 更好"或"React 更好"，要给出具体场景。
>
> **高分回答：**
> "选型取决于团队规模、项目复杂度、技术栈要求：
>
> 1. **中小团队 + 快速迭代 + 中后台**：选 Vue。开箱即用，学习曲线低，官方生态完整（Vue Router + Pinia + Vite），团队不需要做太多技术决策。
> 2. **大型团队 + 复杂应用 + 跨端需求**：选 React。生态丰富（Redux/Zustand/MobX、React Native、Next.js），灵活度高，社区最大。
> 3. **已有技术栈**：如果团队已经在用某个框架，不要轻易换。迁移成本远大于框架差异带来的收益。
> 4. **个人学习**：建议两个都学。理解 Vue 的'自动追踪'和 React 的'手动声明'，对理解前端架构非常有帮助。
>    **核心观点**：框架是工具，不是信仰。选哪个不重要，重要的是理解背后的设计理念。"

> [accordion] Vue 的 v-model 和 React 的受控组件有什么区别?
>
> **答题要点：** v-model 是编译器语法糖，受控组件是手动实现的模式。
>
> **高分回答：**
> "Vue 的 `v-model` 是编译器语法糖——`<input v-model='name' />` 编译为 `value` prop + `onInput` 事件。开发者一行代码搞定双向同步。
>
> React 的受控组件需要手动实现：`<input value={name} onChange={e => setName(e.target.value)} />`。React 故意不提供语法糖，因为它认为'双向绑定让数据流不透明'。强制单向数据流 + 手动事件处理，让数据流向清晰可追踪。
>
> 但 Vue 3 的 `v-model` 本质上也是单向数据流——它编译为 `modelValue` prop + `update:modelValue` 事件，只是语法上更简洁。所以两者的运行时行为是一样的，区别只是开发体验。"

> [accordion] Vue 的 provide/inject 和 React 的 Context 有什么区别?
>
> **答题要点：** 两者都是跨层级传递数据，但实现机制不同。
>
> **高分回答：**
> "Vue 的 `provide/inject` 基于响应式系统——provide 一个 `ref`，inject 的组件会自动响应变化。它不触发整个子树 re-render，只有依赖了该数据的组件才更新。
>
> React 的 Context 基于发布-订阅——Provider 的 value 变化时，所有 Consumer 组件都会 re-render。这是 React Context 的性能瓶颈——即使 Consumer 只用了 value 中的一个属性，整个 value 对象变化也会触发 re-render。
>
> 解决方案：拆分多个 Context、用 `useMemo` 缓存 value、或用 Zustand/Redux 等外部状态管理库替代。Vue 的 provide/inject 没有这个问题，因为响应式系统会精确追踪依赖。"

> [accordion] Vue 的 watch 和 React 的 useEffect 有什么区别?
>
> **答题要点：** watch 是响应式数据变化时触发，useEffect 是组件渲染后触发。
>
> **高分回答：**
> "Vue 的 `watch` 是响应式数据变化时触发——它和响应式系统深度集成，只有被侦听的数据变化时才执行。`watchEffect` 自动追踪依赖，依赖变化时重新执行。
>
> React 的 `useEffect` 是组件渲染后触发——它不关心具体是哪个状态变化了，只要组件 re-render 了，effect 就会重新执行（除非依赖数组没有变化）。`useEffect` 的心智模型是'同步副作用'，不是'响应数据变化'。
>
> 这导致了一个常见问题：React 的 `useEffect` 经常因为依赖数组不正确而出现 bug（过多或过少的执行）。Vue 的 `watch` 更直观——你明确指定侦听哪个数据，数据变了就执行。"

> [accordion] React 的并发渲染和 Vue 的批量更新有什么区别?
>
> **答题要点：** 并发渲染是时间切片 + 优先级调度，Vue 的批量更新是同步合并。
>
> **高分回答：**
> "React 18 的并发渲染（Concurrent Rendering）实现了时间切片和优先级调度：把渲染拆成多个小块，每块执行后检查是否需要让出主线程（`shouldYield`）。高优先级更新（如用户输入）可以打断低优先级更新（如数据加载），以保持交互响应。
>
> Vue 3 的批量更新是同步合并：同一事件循环内的多次数据修改，只触发一次组件更新。通过 `queueJob` + 微任务实现——同步代码执行完后，在微任务中统一刷新队列。Vue 的组件更新一旦开始，不会在中途被打断。
>
> 核心区别：React 的并发渲染是"可中断、可调度的渲染"，Vue 的批量更新是"不可中断的同步渲染"。简单场景下，Vue 少了调度开销；大量组件同时更新的场景下，React 的时间切片有助于保持交互响应。"

***

## 延伸阅读与引用参考

* [Vue 3 官方文档 - Comparison with Other Frameworks](https://vuejs.org/guide/extras/comparison.html)：Vue 官方对 Vue vs React vs Angular 的对比。<sup>\[1]</sup>
* [React 官方文档 - Thinking in React](https://react.dev/learn/thinking-in-react)：React 的设计理念和心智模型。<sup>\[2]</sup>
* [Vue 3 源码 packages/reactivity](https://github.com/vuejs/core/tree/main/packages/reactivity)：Vue 3 响应式系统的核心实现。<sup>\[3]</sup>
* [CMU SEI - Vue vs React: A Comprehensive Guide](https://insights.sei.cmu.edu/blog/2024/04/vue-vs-react-a-comprehensive-guide.html)：CMU 软件工程研究所对 Vue 和 React 的全面对比。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.