从Vue3转向React的核心在于思维转换,1-2周即可上手。
主要差异包括:
- 响应式原理(Vue自动追踪 vs React不可变数据)
- 模板语法(Vue模板 vs React JSX)
- 组件通信方式
学习路径建议:
- 理解React渲染机制;
- 掌握useState等核心Hooks;
- 通过重写Vue项目练习;
- 学习React生态工具。
提供Vue3-React语法对照表,涵盖状态管理、生命周期等常见场景。
Vue优势在开箱即用和开发体验,适合中小项目;
React更灵活且生态强大,适合复杂应用。
技术选型应结合项目需求和团队偏好,二者核心能力高度重合但理念不同。
会 Vue3,学习 React 难度大吗,怎么快速上手
会 Vue3 再学 React,难度其实不大。
核心挑战不在于"复杂度",而在于"编程思维的切换"。
如果你能快速理解下面几个关键差异,通常 1-2 周 就能上手写业务。
一、核心思维差异(最关键)
-
响应式原理 :Vue 是"可变 + 自动追踪",修改
state就直接变了;React 是"不可变 + 显式更新",需要调用setState传入新值,且必须使用不可变数据(如展开数组/对象),否则组件可能不更新。 -
模板 vs JSX :Vue 模板语法受限但简洁;React 用 JSX,本质是 JavaScript,拥有完全编程能力(
.map、三元表达式等),但需要理解"在 JSX 中嵌入表达式"的规则。 -
组件通信 :Vue 有
props和emit;React 只有props,子组件若想通信,需由父组件传递回调函数。这一点需要习惯。
二、快速上手路径
1. 先理解"渲染机制"
花 1 小时重点搞懂:为什么 React 里不能直接改 state?什么是不可变数据?这是新手 80% 报错的根源。
2. 主攻函数组件 + Hooks
你基本不需要学 Class 组件。重点掌握这 4 个 Hooks,它们对应 Vue3 的用法:
-
useState:对应ref/reactive,但解构后丢失响应性,需用setXxx更新。 -
useEffect:对应watch+onMounted/onUnmounted。注意依赖项数组的控制,容易引发无限循环。 -
useMemo&useCallback:对应computed,以及避免子组件无效重渲染。 -
useRef:对应ref用于操作 DOM 或存储不触发渲染的变量。
3. 利用"对标法"写一个 Demo
不要看大而全的教程。直接写一个 Vue 里很熟悉的页面(如 TodoList 或后台列表页),用 React 重写一遍。
过程中重点对比:Vue 的 v-if 对应 JSX 的 {condition && ...};v-for 对应 arr.map();@click 对应 onClick。
4. 工具链与生态
React 本身核心 API 很少。复杂状态管理,若项目不大,直接用 useContext + useReducer 替代 Vuex/Pinia;若项目大,直接学 Zustand(比 Redux 简单太多)。路由直接看 React Router v6 文档,概念和 Vue Router 很像。
三、避坑指南
-
JSX 必须有根元素 :或使用
<></>(Fragment)包裹。 -
避免副作用位置:不要在循环或条件语句中调用 Hooks。
-
样式问题 :React 没有 Scoped CSS,推荐使用 CSS Modules(文件名
*.module.css)或 TailwindCSS,避免样式污染。
只要你 Vue3 的 Composition API 用得顺手,React 这套 Hooks 模式你上手会很快。
建议打开官方文档,直接看"Main Concepts"和"Hooks"部分,结合一个实战项目,基本一周就能上手。
Vue3 到 React 的语法速查对照表
这是一份 Vue3 到 React(函数组件 + Hooks) 的速查对照表,涵盖了日常开发中最常用的场景。
你可以把它当作"翻译词典",边写边查。
一、模板/JSX 语法
| 场景 | Vue 3 | React |
|---|---|---|
| 文本插值 | {``{ message }} |
{message} |
| 绑定属性 | :src="url" 或 v-bind:href="url" |
src={url} href={url} |
| 绑定 class | :class="{ active: isActive }" |
className={isActive ? 'active' : ''} 或使用 clsx 库 |
| 绑定 style | :style="{ color: textColor }" |
style={``{ color: textColor }} |
| 事件绑定 | @click="handleClick" |
onClick={handleClick} |
| 事件修饰符 | @click.stop.prevent |
需要手动调用 e.stopPropagation() / e.preventDefault() |
| 双向绑定 | v-model="value" |
value={value} onChange={e => setValue(e.target.value)} |
二、响应式与状态
| 场景 | Vue 3 (Composition API) | React (Hooks) |
|---|---|---|
| 声明响应式状态 | const count = ref(0) |
const [count, setCount] = useState(0) |
| 访问/修改值 | count.value++ / 模板中自动解包 |
setCount(count + 1) |
| 响应式对象 | const state = reactive({ name: 'vue' }) |
const [state, setState] = useState({ name: 'vue' }) 修改需合并:setState({ ...state, name: 'react' }) |
| 计算属性 | const double = computed(() => count.value * 2) |
const double = useMemo(() => count * 2, [count]) |
| 模板中调用函数 | {``{ formatDate(date) }} |
{formatDate(date)}(但可能每次渲染都执行,如需缓存用 useMemo/useCallback) |
三、生命周期与副作用
| 场景 | Vue 3 | React |
|---|---|---|
| 组件挂载后 | onMounted(() => { ... }) |
useEffect(() => { ... }, []) |
| 组件卸载前 | onUnmounted(() => { ... }) |
useEffect(() => { return () => { ... } }, []) |
| 依赖数据变化 | watch(() => count.value, (newVal) => { ... }) |
useEffect(() => { ... }, [count]) |
| 任意数据变化后同步执行(无依赖) | watchEffect(() => { ... }) |
useEffect(() => { ... })(不加依赖数组,但注意可能无限循环,通常不推荐) |
四、条件与列表渲染
| 场景 | Vue 3 | React |
|---|---|---|
| 条件渲染 (if) | v-if="show" / v-else |
{show && <Component />} 或三元表达式 |
| 条件渲染 (show/hide) | v-show="show" |
通过 style={``{ display: show ? 'block' : 'none' }} |
| 列表渲染 | v-for="item in list" :key="item.id" |
{list.map(item => <div key={item.id}>{item.name}</div>)} |
五、组件通信
| 场景 | Vue 3 | React |
|---|---|---|
| 父传子 | defineProps(['title']) |
子组件接收 props 参数:function Child({ title }) |
| 子传父 | const emit = defineEmits(['update']) emit('update', value) |
父组件传递回调:<Child onUpdate={handleUpdate} /> 子组件调用 props.onUpdate(value) |
| 跨层级传递 | provide / inject |
useContext 或状态管理库 (Zustand, Redux) |
| 组件实例/方法调用 | ref="childRef" + defineExpose |
useRef + useImperativeHandle |
六、插槽 (Slots)
| Vue 3 | React |
|---|---|
默认插槽:<slot /> |
props.children |
具名插槽:<slot name="header" /> |
通过 props 传递 React 节点:<Child header={<div>...</div>} /> |
作用域插槽:<slot :item="item" /> |
通过 render props:<Child>{(item) => <div>{item}</div>}</Child> |
七、路由 (Vue Router vs React Router v6)
| 场景 | Vue Router | React Router |
|---|---|---|
| 定义路由 | routes 数组 + createRouter |
<Routes> + <Route path="/" element={<Home />} /> |
| 路由跳转 | router.push('/about') |
const navigate = useNavigate(); navigate('/about') |
| 链接组件 | <RouterLink to="/about"> |
<Link to="/about"> |
| 获取参数 | route.params.id |
const { id } = useParams() |
| 获取查询参数 | route.query.page |
const [searchParams] = useSearchParams(); searchParams.get('page') |
| 嵌套路由 | children + <RouterView /> |
<Outlet /> |
八、状态管理 (Pinia vs 常用方案)
| 场景 | Pinia (Vue) | React 常用方案 |
|---|---|---|
| 定义 store | defineStore('main', { state, getters, actions }) |
Zustand: create((set) => ({ count: 0, inc: () => set((state) => ({ count: state.count + 1 })) })) |
| 使用 store | const store = useMainStore() |
const { count, inc } = useStore() |
| 异步操作 | actions 中写 async/await |
Zustand 中直接写异步函数,调用 set |
九、常用 Hooks / APIs 对应
| 场景 | Vue 3 | React |
|---|---|---|
| 获取 DOM 元素 | const el = ref(null) |
const el = useRef(null) |
| 父组件调用子组件方法 | defineExpose + ref |
useImperativeHandle + forwardRef |
| 缓存函数 | -- | useCallback(fn, [deps]) |
| 强制更新 | forceUpdate (很少用) |
const [, forceUpdate] = useState({}) |
十、开发工具与配置
-
脚手架 :Vue 用
create-vue,React 用create-react-app或vite(推荐) -
样式隔离 :Vue 有
<style scoped>,React 常用 CSS Modules(*.module.css)或 styled-components -
TypeScript:两者都原生支持,React 中组件 props 需显式声明类型
最后的小建议
初学 React 时,最容易踩的坑是 忘记不可变数据 (直接修改 state 对象/数组)和 useEffect 依赖数组导致的无限循环。
写代码时多问自己一句:"我是否产生了新对象/数组?"
如果你已经把 Vue3 的组合式 API 用得很熟,上手 React 其实只是在换一种写法。
遇到不确定的对应关系,可以回来翻这个表。
Vue和React各自的优势和适用场景是什么,为什么感觉差不多的东西,都有人在用
Vue 和 React 都用于构建前端界面,但它们的设计哲学、上手曲线、生态定位有所不同,所以各自在不同场景下更受青睐。
简单来说:
-
Vue 更像"开箱即用的渐进式框架",注重开发体验和低门槛。
-
React 更像"灵活的 UI 库",强调函数式编程和强大的生态组合能力。
一、Vue 的优势与适用场景
✅ 优势
-
渐进式 :可以从一个简单的
script引入开始,逐步升级到完整框架,对项目侵入性低。 -
模板语法直观:基于 HTML 的模板,对后端/设计背景的开发者非常友好,学习曲线平滑。
-
官方生态完整:路由(Vue Router)、状态管理(Pinia)、构建工具(Vite)都由核心团队维护,开箱即用,配置少。
-
文档出色:中文文档尤其完善,社区在国内非常活跃。
-
性能优秀:采用编译时优化,运行时开销小。
🎯 适用场景
-
中小型项目、管理后台、快速原型------开发效率高,维护成本低。
-
团队技术栈偏向传统(Java/PHP 等后端转前端)------模板语法接近原生 HTML,容易上手。
-
个人开发者或小团队------官方集成度高,减少选型纠结。
-
国内企业项目------Vue 在国内占有率极高,人才易招,社区问答丰富。
二、React 的优势与适用场景
✅ 优势
-
高度的灵活性:JSX 赋予 JavaScript 完全编程能力,逻辑与 UI 更紧密,适合复杂交互。
-
函数式编程范式:状态不可变、纯函数组件、Hooks 组合逻辑,代码可预测性强,便于测试。
-
生态极其丰富:Next.js(全栈框架)、React Native(移动端)、Remix 等,几乎覆盖所有前端领域。
-
大厂背书:Facebook 持续投入,社区规模全球第一,第三方库和解决方案最多。
-
跨平台能力:一套技术栈可构建 Web、移动 App(React Native)、桌面应用(Electron)。
🎯 适用场景
-
大型复杂应用------状态和交互繁多时,函数式组合和严格的单向数据流更易维护。
-
需要跨平台复用的项目------比如同时做 Web 和 App,可共享业务逻辑。
-
追求前沿技术栈的团队------React 生态更新快,新理念(Server Components、并发渲染)往往先在 React 落地。
-
全球性项目或外企------React 在国际市场占据绝对主流。
三、为什么感觉差不多,却都有人在用?
-
解决问题的重叠区
两者都能做 SPA、SSR、移动端,核心能力高度重合,所以在很多场景下确实是"可替换的"。但就像"轿车和 SUV"都能代步,选择往往取决于具体路况和喜好。
-
团队偏好与历史惯性
技术选型常常受创始人或核心工程师的熟悉度影响。Vue 团队更喜欢"约定大于配置"的体验;React 团队偏爱"灵活组合"的控制感。
-
生态与招聘
如果项目需要大量第三方 UI 库(如 Ant Design 在 React 生态更成熟),或需要快速招人(国内 Vue 熟练开发者多),这些现实因素会左右决策。
-
技术理念的差异
Vue 的理念是"提供更少的选择,但让每个选择都足够好";React 的理念是"提供核心机制,让社区自由组合"。前者降低认知负担,后者释放上限。
四、如何选择?
-
追求开发效率、团队经验偏传统、做企业级中后台 → Vue 往往更顺手。
-
需要高度自定义、项目规模大、或未来可能延伸到移动端 → React 更有优势。
-
如果你是独立开发者,两者皆可,选一个深入学习 ------掌握一个后,另一个也能很快上手(就像你从 Vue3 学 React 一样)。
最后,它们都是优秀的技术,持续并存也恰恰反映了前端生态的健康与多样性。
选择适合你的场景和团队的那个,就是最好的。
示例:古茗前端技术栈以 React 为主
根据古茗官方校招职位描述和多篇技术分享,结论非常明确:
✅ 官方招聘明确要求 React
古茗近两年的前端校招 JD 中,任职资格都明确写着:"对 HTML,CSS,JS,React 等前端技术有一定学习和了解" -1-3-4。这说明 React 是官方招聘中明确要求的技术栈。
✅ 内部技术文章证实深度使用 React
古茗前端团队的技术博客和内部架构分享中,多处展示了 React 的深度应用:
-
自研微前端方案 Mars :古茗前端团队基于 React 构建了名为"Mars"的中后台技术架构,通过编译手段约束子应用开发,代码示例全部使用 React-2
-
大前端数据中心:古茗的前端监控平台支持 React 应用的性能监控和日志分析
-
React Native 应用 :面经显示古茗团队有 React Native 项目,会考察"React 和 Native 之间的通信"等 Native 开发相关问题-5
✅ 多端技术栈统一
古茗前端覆盖的业务场景很广,但 React 是核心:
🤔 为什么面经里有人被问 Vue?
你可能会看到牛客网面经里有同学被问到 Vue 原理 (diff 算法、响应式原理、nextTick 等)-5。原因是:
-
古茗团队要求前端基础扎实 ,面试官认为 Vue 和 React 的底层原理相通(虚拟 DOM、组件化等),考察 Vue 原理本质是在考察你对前端框架通用机制的理解深度
-
古茗部分历史项目或小程序可能使用 Vue/uni-app,但不影响 React 作为主技术栈的地位