Skip to content

Vue 与 React 对比

Vue 和 React 是前端两大主流框架。选型时最常听到的一句话是"差不多,团队熟哪个用哪个"——但真要较真,它们的设计哲学、数据流、版本节奏差异很大。这篇把 Vue 2 / Vue 3 与 React 16 → 19 各版本横着比一遍,帮你建立坐标系。

先说结论:两个框架如今都很好用,差异在"设计理念"而非"能力强弱"。Vue 的哲学是"渐进式、上手快、模板贴近 HTML";React 的哲学是"函数式、显式、一切皆组件"。它们互相学习了很多——Vue 3 的 Composition API 借鉴了 React Hooks,React 的服务器组件借鉴了框架的 SSR 思路。

版本对应关系先摆平

比之前先把版本线对齐,这是最容易混的:

时间线VueReact时代特征
2014-2019Vue 2.xReact 15 / 16组件化普及,Vuex / Redux 定型
2020Vue 3(Composition API)React 17(无新特性)Vue 大版本重写
2022Vue 3.2 / 3.3 稳定React 18(并发渲染)双方都进入成熟期
2024-至今Vue 3.4+React 19(编译器/服务器组件)AI 时代前端工具链重构

关键认知:Vue 2 → 3 是"推翻重写"(连响应式内核都换了),React 16 → 19 是"同内核渐进升级"。这决定了升级成本完全不是一个量级。

核心差异一:响应式模型(最根本的分歧)

这是两个框架最本质的区别,理解了这一个,其他都能推出来。

Vue:自动追踪(数据变了,视图自动更新)

Vue 3 用 Proxy 代理数据对象,读取时自动收集依赖、修改时自动通知——你不需要告诉框架"我改了数据",它自己知道:

html
<script setup>
import { reactive } from 'vue';

const state = reactive({ count: 0 });
function add() { state.count++; } // 改完视图自动更新,无需额外动作
</script>
<template>
  <p>count: {{ state.count }}</p>
  <button @click="add">+1</button>
</template>

实跑验证过:新增属性、删除属性、数组 push,全都自动响应(Vue 2 时代新增属性需要 Vue.set,这是 Vue 3 重写响应式的最大红利)。

React:显式更新(你告诉框架"该变了")

React 的数据流是单向 + 显式:改数据必须调 setState,而且提倡不可变更新(生成新对象,而不是改旧对象):

jsx
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const add = () => setCount(count + 1); // 必须显式 setState
  return <p>count: {count}</p> <button onClick={add}>+1</button>;
}

React 的哲学:UI 是状态的函数 UI = f(state)——你给一个新 state,React 重新算一遍视图(通过虚拟 DOM diff 找出最小变化)。它不追踪"谁读了数据",而是"每次 setState 后整个组件重跑"。

维度Vue 3(Proxy 自动追踪)React(显式 setState)
改数据直接赋值 state.count++setCount(count + 1)
新增属性自动响应需要展开对象 setObj({...obj, new: 1})
更新粒度精确到属性组件级重渲染(靠 memo 优化)
心智模型"数据变了视图自动跟""给个新状态,我重算"

一句话:Vue 像"你改了 Excel 单元格,公式自动重算";React 像"你重新提交一份报表,系统重新出图"

核心差异二:模板 vs JSX

Vue:模板,贴近 HTML

Vue 写页面几乎就是 HTML 加指令,学习成本低,设计师都能看懂:

html
<template>
  <div v-if="visible" class="card" @click="open">
    <span>{{ user.name }}</span>
  </div>
</template>

React:JSX,JS 里写标记

React 的组件就是 JS 函数,UI 是函数返回值(JSX 是语法糖):

jsx
function Card({ user, visible, onOpen }) {
  if (!visible) return null;
  return (
    <div className="card" onClick={onOpen}>
      <span>{user.name}</span>
    </div>
  );
}
维度Vue 模板React JSX
形态HTML + 指令(v-if/v-for)JS 表达式 + {}
条件渲染v-if / v-show三元 / && / 提前 return
循环v-for + :keymap() + key
事件@clickonClick
学习曲线平缓(像 HTML)陡(要先会 JS)
自由度模板受限(有逻辑约束)完全 JS,随意表达

现在的趋势:Vue 也支持 JSX(render 函数),React 生态也出了 for 指令之类的模板化尝试(React Compiler)。双方在互相靠拢,但各自的主流写法不变。

核心差异三:状态管理

前端的状态管理是"选框架送配菜",版本和方案都要对齐:

框架Vue 2Vue 3React
官方方案Vuex 3PiniaRedux Toolkit / Zustand
特点必须 commit直接改 state不可变 + 中间件
学习成本中(概念多)低(4 个概念)Redux 高 / Zustand 低
  • Vue 侧:Vuex → Pinia 的演进本质是"去仪式感"(详见 Pinia 状态管理详解
  • React 侧:Redux 是 Flux 架构正统(action → reducer → store),样板代码多;Zustand 近年因轻量(无 Provider、API 类似 Pinia)流行
  • 共同点:都是单向数据流 + 集中式 store,概念相互借鉴

核心差异四:逻辑复用

组件之间的逻辑怎么共用,两个框架走了不同路线:

方案VueReact
Vue 2mixin(易冲突)HOC / render props
Vue 3ComposableuseXxx()HooksuseXxx()
共性都是"把逻辑抽成函数"同左

Vue 3 的 composable 和 React Hooks 长得几乎一样——都是 use 前缀、内部用 ref/state、按需调用。区别在细节:

  • React Hooks 有调用规则:不能写在条件分支里、依赖数组要手动声明(useEffect 的闭包陷阱是经典坑)
  • Vue composable 没这些限制:watch/computed 在任何上下文都能用,自动追踪依赖,心智负担更小

性能与生态:难分伯仲

维度Vue 3React 18+
虚拟 DOM有(编译期优化,静态节点跳过 diff)有(React Compiler 自动 memo)
包体积更小(~34KB gzip)更大(~45KB gzip,含 runtime)
构建工具Vite(Vue 官方首选)Vite / Next.js
SSR 框架NuxtNext.js
移动端无官方方案(可 Capacitor)React Native(成熟)
生态成熟度成熟更庞大(npm 包最多)

性能层面两者都在同代水平——Vue 靠编译期优化,React 靠编译器 + 并发特性,实际差距远小于营销话术。

怎么选:一张决策表

你的情况推荐
团队偏后端/全栈,HTML 熟Vue(模板上手快)
团队偏 JS/TS 函数式React(JSX 无学习断层)
中小项目快速交付Vue(脚手架 + 中文生态友好)
大厂机会/求职面最广React(岗位量更大)
需要移动端原生体验React Native
招人容易React;招 Vue 熟手在二线城市反而好招

务实的建议:框架只是工具,核心能力是"组件化思维 + 状态管理 + 构建工具链",这些两个框架通用。前端面试高频考点是"Vue 和 React 的响应式区别"——能把本文第一张表讲透,就是加分项。


版本提醒:Vue 的版本差异(Vue 2 的 options API / Vue 3 的 Composition API)见 Vue 版本演进:Vue 2 与 Vue 3 全对比;React 侧从 18 到 19 主要变化是并发渲染 + React Compiler,属于渐进升级。

链式导航:Vue 侧细节——响应式原理见 Vue 响应式原理详解,组合式 API 见 Composition API 详解,路由见 Vue Router 路由详解,状态管理见 Pinia 状态管理详解