在当今前端生态中,Vue3和React作为两大主流框架,各有其独特的优势。本文将为Vue3开发者系统梳理过渡到React所需的关键思维转换和技术调整。我是前端小白,花了一星期简单的学习了一下react的基础知识,一直以来都用vue框架开发,先是要求用原生微信小程序写个小程序,现在要来学习react。
1.核心范式差异
Vue3采用"渐进式框架"设计,提供官方全家桶解决方案,强调"约定优于配置"。React则定位为"UI构建库",只处理视图层,其他功能依赖社区生态,奉行"组合优于继承"原则。
2.模版系统差异
Vue的单文件组件(SFC)将模板、逻辑和样式分离:
<template>
<button @click="increment">{{ count }}</button>
</template>
React则采用JSX实现JavaScript与UI的混合表达:
<button onClick={increment}>{count}</button>
3.实践心得
刚接触到react时,就发现react启动服务npm start 比vue启动服务要慢好多,默认用的是webpack构建。而且还不同于vue的构建,没有配上任何路由和状态管理。后来发现react也可以用vite构建。
组件化开发的话,react和原生js像,react可以在js中写html,因为有jsx。区别于vue有专门的.vue写组件,react组件分为两类:一类是函数组件,一类是class组件,就跟vue3,vue2一样的版本。react老版本用的是class组件,新版本用的是函数组件,之前学过java、ts倒也能适应。
在事件绑定上,react类似原生,on + 方法名(首字母大写区分原生),还不能像vue一样直接调用这个方法,要给方法调用bind规定this或方法本身写成箭头函数,传递参数也要借助bind()方法。
在响应式数据上,react不能像vue一样直接修改 触发更新,react修改能改值,但无法触发更新,因为react没有像vue一样监听get和set,而是在调用setState的时候调用react的更新操作,用setState通过浅合并来修改数据,感觉跟原生微信小程序有点像。在双向绑定上,React 通过 手动绑定 value 和 onChange 实现双向绑定,需显式调用 setState 更新数据,习惯用vue的model绑定的我在这方面慢了。
到react中的样式操作css上,感觉好麻烦啊,一度学不下去了。在生命周期的执行上,vue是因为在get和set里触发更新,vue在get部分有一个重要的操作-依赖收集,在更改了数据之后,只会更新用到这个数据的地方,做到最小的更新范围,而react的更新是调用方法时触发的,并没有依赖收集的过程,所以它会更新整个组件树,比如修改父组件,会把子组件一起更新,即便是更新的数据和子组件没有任何关系,不过用PureComponent可以阻止。在ref上原理一个道理,在vue中创建方式是ref()函数,react是createRef()或useRef(),访问值vue是.value,react是.current。学到了高阶组件,第一次听说高阶组件,看学习视频上说类似于vue中的mixin,我去搜了一下已经被Vue3标记为不推荐使用,推荐使用Composition API来实现代码复用,高阶组件是复用操作逻辑,运算的,我在vue3用自定义指令(Directives)做了防抖点击指令功能,跟react的高阶指令还挺相似的。
在路由上,react在各自组件就能够实现路由功能,的确自由,vue3是将路由统一封装到router/index.js文件中,react用BroserRouter包裹要使用路由的根组件,使用Routes组件,定义具体路由显示区域,使用Route组件,定义具体路由规则,使用NavLink组件,定义调整链接,嵌套路由,vue3通过嵌套,react通过组件;动态路由都是通过 : 参数;编程式导航vue3用router.push/replace(),react使用useNavigate();懒加载vue3使用() => import 动态导入,react用lazy() + ;还有路由参数,react的params用useParams(),query用useSearchParams()(返回URLSearchParams对象,结构成一个数据和方法,跟useMemo的hook相似),loacation用useLocation(),vue3都是useRoute(),state传递,react是通过navigate的state选项,vue3是通过router.push的state选项;react的路由管理也可以像vue3一样写成列表渲染;
在状态管理上,React,没有专门的状态管理库,都是通用的js状态管理库,所以我们首先创建一个全局的数据储存和管理工具,通过其他工具,数据的修改能触发react页面的更新。
组件库的话,vue3我习惯用elementPlus ,react用Ant Design。
路由和状态管理在Vue3和React都很重要,用代码展示一下:
react基础用法:
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { Suspense, lazy } from 'react'
const Home = lazy(() => import('./views/Home'))
const About = lazy(() => import('./views/About'))
const User = lazy(() => import('./views/User'))
function App() {
return (
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/user/:id" element={<User />} />
</Routes>
</Suspense>
</BrowserRouter>
)
}
嵌套路由:
<!-- 父路由组件 -->
<template>
<div>
<router-view></router-view> <!-- 子路由出口 -->
</div>
</template>
<!-- 路由配置 -->
{
path: '/parent',
component: Parent,
children: [
{ path: 'child', component: Child }
]
}
// 父路由组件
function Parent() {
return (
<div>
<Outlet /> {/* 子路由出口 */}
</div>
)
}
// 路由配置
<Route path="parent" element={<Parent />}>
<Route path="child" element={<Child />} />
</Route>
编程式导航传参:
import { useNavigate } from 'react-router-dom';
function Component() {
const navigate = useNavigate();
// 传递params
navigate('/user/123');
// 传递query
navigate('/user?name=John');
// 传递state
navigate('/user', { state: { from: 'home' } });
}
import { useRouter } from 'vue-router';
const router = useRouter();
// 传递params
router.push('/user/123');
// 传递query
router.push({ path: '/user', query: { name: 'John' } });
// 传递state
router.push({ path: '/user', state: { from: 'home' } });
响应式参数变化:
// 需要手动监听变化
import { useEffect } from 'react';
import { useParams } from 'react-router-dom';
function User() {
const { id } = useParams();
useEffect(() => {
// 当id变化时执行
}, [id]);
}
<script setup>
import { watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
// 自动响应式
watch(() => route.params.id, (newId) => {
// id变化时自动触发
});
</script>
全局状态:
// store.js
import { createStore } from 'redux'
function counterReducer(state = { value: 0 }, action) {
switch (action.type) {
case 'increment':
return { value: state.value + 1 }
default:
return state
}
}
const store = createStore(counterReducer)
// 组件中使用
import { useSelector, useDispatch } from 'react-redux'
function Counter() {
const count = useSelector(state => state.value)
const dispatch = useDispatch()
return (
<button onClick={() => dispatch({ type: 'increment' })}>
{count}
</button>
)
}
// stores/counter.ts
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
getters: {
doubleCount: (state) => state.count * 2
},
actions: {
increment() {
this.count++
},
async fetchData() {
// 异步操作
}
}
})
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
<div>{{ counter.count }}</div>
<div>{{ counter.doubleCount }}</div>
<button @click="counter.increment()">+</button>
</template>
4.总结
vue3:使用模板语法(.vue单文件组件),通过v-bind、v-on等指令绑定数据与事件,更接近 HTML 语法,直观易读。React:采用 JSX 语法,将 HTML 与 JavaScript 融合,以 JavaScript 表达式嵌入 UI 逻辑,更强调代码的动态性与灵活性。建议深入学习 React 的核心概念,如 hooks、JSX、单向数据流,理解其与 Vue3 的本质区别。可能是刚学react的知识,感觉还是Vue3我用着好使,有好多已经封装好的直接用,不过react在某些方面的确灵活,都说大项目用react好,来学习一下。