返回首页

React 和 Vue 对比

布莱克2026-05-15 10:48已编辑
Tip:文章封面与内容无关,作者旅游时拍摄,因为没什么值得把四季都错过!

Vue

声明式 + 响应式编程 + 可变数据 Vue的核心心智模型是:你修改数据,UI自动更新

// Vue的编程方式
const state = reactive({ count: 0 })
state.count++  // 直接修改,UI自动响应

// 你关注的是:修改数据这个动作
// 框架帮你处理:数据变了 -> 重新渲染哪些部分

精准订阅 (代理 + 响应追踪)

  • 内部用 Proxy 拦截 data 的 getter/setter。
  • 修改数据时,Vue 知道具体哪个组件、哪个属性依赖了这个数据。
  • 更新时:只重新渲染依赖该数据的那个最小组件(非常精准)。

React

声明式 + 函数式编程 + 不可变数据  React的核心心智模型是:UI = f(state),即UI是状态的纯函数输出。

// React的编程方式
const [count, setCount] = useState(0)
setCount(count + 1)  // 你告诉React:新状态是什么

// React内部做的是:
// 旧状态 -> 新状态 -> 重新执行整个组件函数 -> 生成新UI

重新执行整个组件函数

  • 没有任何 Proxy 或依赖追踪。
  • setState 触发后,React 不知道该组件里哪些地方用了这个 state。
  • 解决方案:重新执行整个组件函数,重新计算所有 JSX。
  • 对比:React 的更新粒度是组件级别(虽然最终 diff 算法能复用大部分 DOM,但函数会从头跑一遍)


Vue 的更新流程

简单、同步、确定性

  1. 修改数据 → 触发 setter
  2. 通知所有依赖的 Watcher
  3. 将 Watcher 放入微任务队列(Promise.then)
  4. 同一事件循环中批量执行 Watcher
  5. 每个 Watcher 执行 beforeUpdate → 生成新虚拟 DOM → diff → 更新真实 DOM
  6. 整个过程不可中断


React 的更新流程

Fiber + 优先级 + 可中断

  1. setState → 创建更新对象,进入调度阶段(Scheduler)
  2. 根据优先级(用户点击 > 动画 > 网络请求)安排任务
  3. 协调阶段(Reconciliation):可中断:高优先级任务(如输入框事件)可以打断低优先级的更新低优先级更新可能被丢弃,等空闲时重新执行使用 双缓存 Fiber 树(current 树显示界面,workInProgress 树在内存中构建)
  4. 提交阶段(Commit):同步、不可中断将 workInProgress 树的变化应用到真实 DOM双树切换(新的 current 树指向 workInProgress)


Vue的Dom更新是异步批量更新,react呢,每个setState都会触发更新吗?

在 React 中,多个 setState 默认情况下不会导致每个都触发一次组件函数重新执行,而是会合并成一次重新执行

React 在合成事件中批量更新(一次渲染),在异步代码中老版本会多次渲染,React 18 后基本都能批量


如何理解react的合成事件?

合成事件是 React 自己实现的一套跨浏览器的原生事件包装层。它并不是直接绑定到具体的 DOM 元素上,而是统一绑定在根容器上,采用事件代理机制

  1. React 在组件渲染时,不会给每个 button 单独绑定 click 事件
  2. React 在根容器(如 document 或 root 节点)上只绑定一个事件监听器
  3. 当用户点击按钮,真实 DOM 事件冒泡到根容器
  4. React 根据事件的 target 找到对应的虚拟 DOM 和组件
  5. React 创建合成事件对象(SyntheticEvent)并调用你写的 handleClick


什么是Fiber

待学习


Hook

让你从一个普通函数(组件函数)内部,“伸出一个钩子”去钩住React的核心功能(状态、副作用、上下文等),然后把这些功能“拉”到你的组件里使用

function MyComponent() {
  // 用 useState 这个“钩子”,钩住 React 内部的状态管理
  const [count, setCount] = useState(0)
  
  // 用 useEffect 这个“钩子”,钩住 React 的渲染生命周期
  useEffect(() => {
    document.title = `点击了${count}次`
  }, [count])
  
  return <button onClick={() => setCount(count+1)}>点我</button>
}
React Hook作用Vue 3 对应
useState声明响应式状态ref / reactive
useEffect处理副作用(DOM操作、请求、定时器)watchEffect / watch
useContext获取跨层级数据inject
useRef保存一个不触发重新渲染的值 / DOM引用ref (同名的,注意区分)
useMemo缓存计算结果computed
useCallback缓存函数引用没有直接对应,但Vue不需要(因为函数不会无故重新创建)
useReducer复杂状态逻辑(类似Redux)通常用 reactive + 方法



assistant