您现在的位置是:首页 >其他 >一文看透Vue3 与 React 全方面对比网站首页其他
一文看透Vue3 与 React 全方面对比
1.1 编程风格
React
语法少、难度大;Vue
语法多,难度小
例如指令:
Vue
<input v-model="username"/>
<ul>
<li v-for="(item,index) in list" :key="index">{{ item }}</li>
</ul>
React
<input value={username} onChange={e => setUsername(e.target.value)}/>
<ul>
{ list.map((item,index) => <li key={index}>{item}</li>) }
</ul>
Vue
给我们提供了很多的指令功能,而这些功能在 React
中基本都需要我们使用原生 js
来实现。
所以会有很多人说: “使用 Vue 实际上你就是在操作 Vue,使用 React 实际上你是在操作 js”。
- React 魔改少,手动实现;Vue 魔改多,自动完成。
例如事件:
Vue
<button @click="handleClick('hello')">点击</button>
const handleClick = (msg) => {
console.log('msg')
}
React
<button onClick="handleClick('hello')">点击</button>
const handleClick = (msg) => {
return () => {
console.log(msg)
}
}
像在点击事件中传参数这种功能:
- 我们知道
dom
的点击事件是需要我们传递一个函数过去的,就像在React
中例子一样,你的handleClick
肯定需要返回一个函数(或者在jsx
中写箭头函数调用handleClick
)。 - 而在
Vue
中可以在@click
中直接调用handleClick
函数,而这个函数又没有返回一个新的函数,按道理这样调用handleClick
是会返回undefined
的,但是由于Vue
底层做了魔改优化,使得我们不再需要在返回一个函数。
上面两个例子中,我们说不上哪种好哪种不好,只能说你更喜欢哪一种。React
中的实现更符合 js
的逻辑但却稍显麻烦,Vue
中的实现简单但却没有遵循原生 js
的特点。
编程风格上的总结:就像我们前面讲的,Vue
写起来更像是写 Vue
代码,React
写起来更像是写 JavaScript
代码。
1.2 视图风格
Vue
采用<template>
字符串模板。更贴近HTML
,学习成本低,但有时候不灵活。React
采用JSX
语法,更类似于js
,限制比较多,(像一些关键字class
、for
,单标签要闭合、属性要驼峰、组件名要大写等等这些都要注意),但是可以跟模板语法很好的进行结合
比如下面是一个通过 level
的值来渲染不同的标签在 Vue
和 React
中的不同实现
Vue
<template>
<h1 v-if="level === 1">标题1</h1>
<h2 v-if="level === 2">标题2</h1>
</template>
React
let App = () => {
const level = 1
const Tag = 'h' + level
return (
<div>
{ <Tag>标题{level}</Tag>}
</div>
)
}
可以想象,如果当我们的条件判断很多时,使用 JSX
的方式会比使用模版字符串要灵活的多。
注意: Vue
一开始并不直接支持 JSX
,在 Vue 2.1.0
版本中,Vue
引入了 render
函数来代替模板,这使得使用 JSX
作为组件渲染函数成为可能。在Vue 2.1.0
版本后的 create-vue
和 Vue CLI
都有预置的 JSX
语法支持。所以说在 Vue
中如果你想写 JSX
这个它也是支持的,但是在 React
是没办法用字符串模板的方式写。
2. 组件 & 路由 & 状态管理
2.1 组件风格
Vue2
中采用 选项式 API,但是由于它不够灵活,而且this
指向不够简单,Vue3
中给我们提供了 组合式API 的写法,组合式 API 更偏向函数式编程的方式,它的复用能力和组合的能力更强,而且没有this
指向问题,也是Vue
比较推荐的写法。React
在16.8
版本之前都是采用类组件的方式开发,类组件也会有this
指向以及写起来很繁琐难度大的问题,在16.8
之后React
提供了函数组件的写法,其实函数组件和Vue
的 组合式 API 是很像的,它的组合和复用的能力更强,而且也没有this
指向问题,比类组件写起来简单很多,也是React
比较推荐的写法
Vue 组件示意图:
<template>
<div class="my-component">
<!-- HTML模板 -->
</div>
</template>
<script>
export default {
// JavaScript代码
}
</script>
<style>
.my-component {
/* CSS样式 */
}
</style>
React 组件示意图:
import React from 'react';
import './MyComponent.css';
function MyComponent() {
// JavaScript代码
return (
<div className="my-component">
{/* HTML模板 */}
</div>
);
}
export default MyComponent;
总结:这两种框架它们的最终趋势都是函数式编程,不管是 Vue
还是 React
都是推荐我们引入大量内置的函数或者是 use 函数来进行组合并且完成我们的开发需求。而简化使用面向对象或者是配置的写法,能简化我们使用 this
的场景从而提升代码的灵活度和简易度。
2.2 路由风格
Vue` 采用 `Vue-Router`;React 采用 `React-Router
相比而言 vue
语法更加简练(useRouter useRoute),而 react
的 use 函数太多,不够统一化(useLocation、useParams、useSearchParams、useNavigate…)
而像下面这些常规的功能它们都是大差不差的:
- 路由表的配置
- 嵌套路由
- 动态路由
- 编程式路由
- 守卫路由
Vue-Router 示例代码
<!-- index.html -->
<div id="app">
<router-view></router-view>
</div>
// main.js
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
})
const app = createApp({
// 空的 `setup` 函数
setup() {}
})
app.use(router)
app.mount('#app')
<!-- Home.vue -->
<template>
<div>
<h1>Home Page</h1>
<button @click="goToAbout">Go to About Page</button>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const goToAbout = () => {
router.push('/about')
}
</script>
<!-- About.vue -->
<template>
<div>
<h1>About Page</h1>
<p>Param: {{ $route.params.id }}</p>
<router-link to="/">Go to Home Page</router-link>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const id = route.params.id
</script>
React-Router 示例代码
import React from 'react'
import { BrowserRouter as Router, Switch, Route, Link, useParams, useHistory } from 'react-router-dom'
import Home from './components/Home'
import About from './components/About'
const App = () => {
return (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<hr/>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
</div>
</Router>
)
}
const Home = () => {
const history = useHistory()
const handleClick = () => {
history.push('/about')
}
return (
<div>
<h1>Home Page</h1>
<button onClick={handleClick}>Go to About Page</button>
</div>
)
}
const About = () => {
const { id } = useParams()
return (
<div>
<h1>About Page</h1>
<p>Param: {id}</p>
<Link to="/">Go to Home Page</Link>
</div>
)
}
export default App
2.3 状态管理风格
Vue` 采用 `Vuex/Pinia` ;`React` 采用 `Redux/Mobx
区别:
- 语法和
API
的不同:Vuex
和Pinia
是专门为Vue.js
设计的状态管理库,因此它们的语法和API都非常类似。而Redux
和Mobx
可以在任何JavaScript
应用程序中使用,因此它们的语法和API与特定的框架无关。 - 数据流的不同:在
Redux
中,数据是通过单向数据流进行管理的,即action -> reducer -> store -> view
。而在Vuex
和Pinia
中,数据是通过Vuex store
或Pinia store
直接管理的,不需要reducer
。而在Mobx
中,数据则是通过响应式数据实现的。 - 异步处理的不同:在
Redux
中,异步处理通常需要使用中间件来处理异步操作。而在Vuex
和Pinia
中,异步操作可以通过actions
处理。而在Mobx
中,则可以使用async/await
或reaction
函数来处理异步操作。 - 开销和复杂性的不同:
Redux
和Mobx
都需要在应用程序中进行额外的设置和配置,并且在处理大量数据时可能会导致性能问题。而Vuex
和Pinia
的设置和配置相对简单,并且在大多数情况下可以处理大量数据。
总的来说,Vuex
和 Pinia
适用于 Vue.js
应用程序,提供了一种简单和直接的状态管理方式,而 Redux
和 Mobx
则可以在多种应用程序中使用,提供了更灵活的状态管理方案。
Pinia 示例代码
// store.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore({
id: 'counter',
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++
},
},
})
<!-- App.vue -->
<template>
<div>
<h1>Count: {{ count }}</h1>
<button @click="incrementCount">Increment</button>
</div>
</template>
<script setup>
import { defineComponent } from 'vue'
import { useCounterStore } from './store'
const counterStore = useCounterStore()
const count = counterStore.count
const incrementCount = () => {
counterStore.increment()
}
</script>
<!-- 在根组件中注入 store -->
<script>
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')
</script>
Redux Toolkit 示例代码
// store.js
import { configureStore, createSlice } from '@reduxjs/toolkit'
const counterSlice = createSlice({
name: 'counter',
initialState: {
count: 0
},
reducers: {
increment(state) {
state.count++
}
}
})
export const store = configureStore({
reducer: {
counter: counterSlice.reducer
}
})
export const { increment } = counterSlice.actions;
// App.js
import { useSelector, useDispatch } from 'react-redux'
import { increment } from './store'
function App() {
const count = useSelector(state => state.counter.count)
const dispatch = useDispatch()
const incrementCount = () => {
dispatch(increment())
}
return (
<div>
<h1>Count: {count}</h1>
<button onClick={incrementCount}>Increment</button>
</div>
)
}
export default App
// 在根组件中注入 store
import { Provider } from 'react-redux'
import { store } from './store'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
3. 一些基础功能
3.1 模板对比
Vue
的视图变化主要通过:指令 + 模板的方式
React
的视图变化主要通过:原生JS + 模板的方式
React
的模板比较强大,因为可以编写 JSX
结构,所以可以做出更加灵活的结构处理。
3.2 样式对比
Vue
的 class
和 style
都有三种写法:字符串、数组、对象
React
的 style
只能写对象,class
只能字符串,可借助 classnames
这个库
两个框架基本上都可以满足常见的样式需求。
3.3 事件对比
Vue
事件功能丰富
React
事件传参需要高阶处理
<!-- Vue -->
<template>
<ul>
<li v-for="item,index in list" @click="handleClick(index)"></li>
</ul>
</template>
<script>
methods: {
handleClick(index){
}
}
</script>
<!-- React -->
<ul>
{
list.map((v, i)=> <li onClick={handleClick(i)}></li>)
}
</ul>
const handleClick = (index) => {
return () => {
console.log(index)
}
}
3.4 表单对比
Vue` 表单双向绑定 `v-model
React
表单受控与非受控
针对表单操作这一块来说,Vue
的表单指令 v-model
还是非常灵活的,总体对比要比 React
使用方便且灵活。
3.5 组件通信对比
Vue
父子组件通过 props
属性通信,子父组件通过 emits
方法通信
React
父子组件也是通过 props
属性通信,而子父组件则是通过回调函数通信的
emits
自定义事件和回调函数,实际上是一样的思想。
跨组件的通信方案也很类似,都是一种依赖注入的方式来实现的。
3.6 逻辑复用
Vue` 选项式采用:`mixins混入`;组合式采用:`use函数
React` 类组件采用:`Render Props`、`HOC`;函数组件:`use函数
可以发现组合式API和函数组件都是采用use函数,所以基本复用是差不多的思想,这也是两个框架推荐的用法。
3.7 内容分发
Vue
通过插槽,进行接收
React
通过 props.children
,进行接收
3.8 DOM操作
Vue
通过 ref
属性
React
也通过 ref
属性处理
思路都是差不多的,就是给元素添加 ref
属性,在跟对象或字符串绑定在一起,这样就可以直接获取到 DOM
元素。
4. 响应式 & 生命周期 & 副作用
4.1 响应式数据对比
Vue采用响应式数据,底层通过new Proxy()进行监控,灵活性更高
React采用state状态,通过setState()方法进行内部re-render,可控性更强
4.2 生命周期对比
Vue生命周期钩子(常见)
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeUnmount
- unmounted
React生命周期钩子(常见)
- constructor
- componentDidMount
- componentDidUpdate
- componentWillUnmount
- render 整体对比来看,
Vue
的生命周期会更丰富一些,React
生命周期会更简约一些。
4.3 副作用处理对比
vue使用,watchEffect()
react使用,useEffect()
都是处理副作用的方法,用法上还是有很大区别的。
watchEffect会自动根据所依赖的值进行重渲染,而useEffect要明确指定对应的值才能进行重渲染,React团队已经给出在未来的版本中可能会改成根据所依赖的值自动进行重渲染的操作,但暂时还不行。
watchEffect在更新前和卸载前触发的方式是通过回调函数的参数被调用来实现的,而useEffect是通过return的返回值来指定的。
// Vue
watchEffect((cb)=>{
cb(()=>{
//更新前的触发
})
})
// React
useEffect(()=>{
return ()=>{
//更新前的触发
}
})
Vue3 与 React 对比总结
1、Vue上手更简单,特别是从dom和jquery时代过来的程序员,或者习惯模板语言的后端开发,更容易接受Vue。
2、Vue从设计上讲,跟趋向于简化使用,就是说Vue从骨子里面就是想用起来简单,但React更多的是为大型工程考虑。
3、React上手稍微难一点,除了Vue那些基础,你还得学习,纯函数组件,函数式编程,JSX,css-in-js,高阶组件,Redux等。
4、在组件化上,React更纯粹,也可以说更强大一些,而Vue不是完全组件化,应对一些复杂组件,可能会有些麻烦。
5、React的设计,配合TypeScript,更适合大型或者超大型的多人协作项目,管理起来更规范,不容易出错。
6、对于移动端跨平台的支持,React的兄弟项目ReactNative已经占了半壁江山,虽然React和ReactNative可以看成两个东西,但是也有很多关联性。而Vue在移动端开发上,目前来看,有阿里的Weex基于Vue,据说也很强大,但是肯定不如ReactNative那么主流和稳定,具体Vue在移动端的表现如何,需要时间观察。
7、虽然Vue在中国、日本、韩国、法国等地区热度很高,在美国也有一定影响力,但在全世界范围看,React的社区比Vue要更大,资源也更丰富,React的背景Facebook,实力强于个人开发者-尤雨溪(背靠了阿里和一些小赞助公司)。但实力是相对的,实际上,两者实力都很强,不用担心Vue的实力不足或稳定性,Vue足够优秀,3、5年内应该都会是主流,只能说React在全世界范围内的资源更多,影响更大而已。
8、Vue和React本身只是一个基础库,对于稍微复杂一点的项目来说,大多数用户都不会自己搭框架。所以说,选择Vue还是React,要重点比较两者的第三方开发框架、UI框架、组件库及各种资源是否丰富、有活力。
9、就我目前看到的情况而言,Vue体系较热的UI框架有ElementUI、iView/ViewUI、Ant Design Vue、vant、mint-ui、vux等,Vue Admin(后台管理系统)相关资源比较丰富,很多中小公司都在用;React热门UI框架有Material-UI、Ant Design、Element-react等,比较集中。可以这样说,Vue的生态就像是游击队,而React更像是正规军。ElementUI和Ant Design都是阿里系的,如果没有Ant Design的话,感觉Vue在国内要强盛一些,但有了阿里Ant Design强势介入,许多中间派就倒向React了,特别是一些稍微大一点的公司。
10、其他因素:Vue的核心开发团队只有尤雨溪一人(大概90%的代码都是他写的),假如他休假了、生病了,主要开发就暂停了,Vue想要健康的发展,应该要增加1~2个核心开发(每个人都深度参与开发,并可以推动开源生态发展)。
11、其他因素:React从一开始就抱上了TypeScript的大腿,而Vue目前仍以ES为主,不得不说,在很长一段时间内,TS都是优于ES的,而Vue社区要切换TS生态,还有一段路要走。这注定了大公司、大项目选React+TS的概率要大一些。中小公司多少也会受到大公司的影响。
最终总结:
1、如果只是做项目,两者都很好,都是主流,都能极大的增强前端开发能力,选任何一个都没有错(做选择时,可考虑其他一些因素,比如自身能力、第三方组件)。
2、如果想抱大腿、跳槽大公司,建议选React + TypeScript练手。
3、5年以后的长远考虑?这两个的生命力,足以支撑5年,但你要说5年之后,它们是否还是主流,这个真不好说。现在前端技术发展太快。
4、作为一个专业前端,建议前期学Vue的,都再把React了;反之,如果之前直接学的React,则一般不需要再去学Vue了,做项目,选一个就行了