漫谈前端:2025年框架是该选vue还是react?

news/2024/10/4 1:25:07/

相信很多前端小伙伴都有过纠结的时候,开始一个项目的时候是该选vue还是react。很多情况下,都是根据团队现有框架延续,或者是自身数量度。渐渐的公司组件和规范全基于某一种框架,虽然很爽但Allin难掉头。本文就浅浅的比较下vue和react框架,谈一谈个人看法。

目前二者的版本和周下载对比:

名称最新版本周下载(百万次)问题数
vue3.5.105.5642
react18.3.125.8650

 比较可惜的是目前npmjs官网差不多vue2的数据了,react的全球下载量是react的五分之一,而国内npmmirror下载量每周也就0.5m,react稍微小一点0.4m左右。二者都比年初要提升不少,只是vue基数比较小,总体来看vue的用户数量是比react少一些的。但国内react用户量在增加明显

下面将对比下二者使用上的差异,设计和性能就不比较了,其实都差别不太大。

1. 状态管理

Vue 3

在 Vue 3 中,setup 是一个新引入的生命周期钩子,它允许我们通过 refreactive 创建和管理组件内部的状态。setup 函数的主要优点是更容易组织和复用逻辑,尤其是与组合式 API 搭配使用时。

<template><div><p>{{ count }}</p><button @click="increment">Increment</button></div>
</template><script >
import { ref } from 'vue';export default {setup() {const count = ref(0);const increment = () => {count.value++;};return { count, increment };}
};
</script>

在这个示例中,ref 用于声明响应式状态 count,并且 setup 函数返回的数据会暴露给模板。

React (函数式组件)

React 中,状态管理依赖于 useState 钩子。React 的函数式组件(FC)是无状态的,但通过 Hooks(如 useStateuseReducer)可以实现状态管理。
j

import React, { useState } from 'react';const Counter = () => {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1);};return (<div><p>{count}</p><button onClick={increment}>Increment</button></div>);
};export default Counter;

在这个示例中,useState 钩子用于创建和管理 count 的状态,并通过回调函数 setCount 更新状态。

对比

特性Vue 3 (setup)React FC (useState)
状态声明使用 refreactive使用 useState
响应式处理Vue 内置响应式系统React 使用 Hooks,非响应式
逻辑组织组合 API 更易复用逻辑Hooks 使逻辑复用变得灵活
语法复杂度较为简洁,ref.value 语法相对简洁

2. 数据流

Vue 3

在 Vue 3 中,数据流主要通过 props 向下传递,emits 向上传递。父子组件间的数据流较为明确,借助 setup 函数可以简化状态和逻辑处理。

// Parent.vue
<template><Child :message="parentMessage" @reply="handleReply" />
</template><script>
import Child from './Child.vue';export default {components: { Child },setup() {const parentMessage = ref('Hello from Parent');const handleReply = (replyMessage) => {console.log(replyMessage);};return { parentMessage, handleReply };}
};
</script>

React (函数式组件)

在 React 中,数据流也通过 props 传递,父组件可以通过回调函数接收子组件传递回来的数据。

// Parent.js
import React from 'react';
import Child from './Child';const Parent = () => {const parentMessage = 'Hello from Parent';const handleReply = (replyMessage) => {console.log(replyMessage);};return <Child message={parentMessage} onReply={handleReply} />;
};export default Parent;

React 和 Vue 都遵循自顶向下的数据流,但 React 的 props 是单向绑定,Vue 则支持更灵活的双向绑定机制(例如 v-model)。

对比

特性Vue 3 (setup)React FC
数据传递props 向下,emits 向上props 向下,回调向上传递
数据流模式支持单向/双向数据绑定主要是单向数据流
事件处理使用 emits$emit使用回调函数传递事件

3. Provide/Inject(依赖注入)

Vue 3

Vue 3 提供了 provideinject 来实现祖先组件与后代组件之间的通信,允许在组件树中上下层级之间传递数据,而不必通过 props 层层传递。provideinjectsetup 中使用时更加简洁和直观。

 

// Parent.vue
<template><Child />
</template><script>
import { provide, ref } from 'vue';
import Child from './Child.vue';export default {components: { Child },setup() {const message = ref('Hello from Parent');provide('parentMessage', message);}
};
</script>// Child.vue
<template><p>{{ parentMessage }}</p>
</template><script>
import { inject } from 'vue';export default {setup() {const parentMessage = inject('parentMessage');return { parentMessage };}
};
</script>

React (Context API)

React 中没有直接的 provide/inject,但是通过 Context API 实现类似功能。Context 允许在组件树中向下传递数据,无需通过每一级组件手动传递 props

 

import React, { createContext, useContext, useState } from 'react';const MessageContext = createContext();const Parent = () => {const [message] = useState('Hello from Parent');return (<MessageContext.Provider value={message}><Child /></MessageContext.Provider>);
};const Child = () => {const message = useContext(MessageContext);return <p>{message}</p>;
};export default Parent;

对比

特性Vue 3 (provide/inject)React (Context API)
用途祖先与后代组件之间的数据传递全局或层级深的状态共享
语法复杂度相对简单,内置 API相对复杂,需要 Context 和 Hooks
使用场景轻量级依赖注入状态、主题、配置等全局数据

4. 组件管理

Vue 3 (setup)

Vue 3 通过 setup 更容易将逻辑拆分到多个文件或组合函数中,逻辑复用也更灵活。在 Vue 3 中,组合式 API 提供了一种清晰的方式来管理组件的生命周期和逻辑。

示例:通过组合函数(useCounter)将逻辑抽离出来:

// useCounter.js
import { ref } from 'vue';export function useCounter() {const count = ref(0);const increment = () => {count.value++;};return { count, increment };
}// Counter.vue
<template><div><p>{{ count }}</p><button @click="increment">Increment</button></div>
</template><script>
import { useCounter } from './useCounter';export default {setup() {const { count, increment } = useCounter();return { count, increment };}
};
</script>

React (函数式组件)

React 使用 Hooks 进行逻辑复用和组件管理,通过自定义 Hooks 可以将组件的逻辑抽离和复用。

示例

// useCounter.js
import { useState } from 'react';export const useCounter = () => {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1);};return { count, increment };
};// Counter.js
import React from 'react';
import { useCounter } from './useCounter';const Counter = () => {const { count, increment } = useCounter();return (<div><p>{count}</p><button onClick={increment}>Increment</button></div>);
};export default Counter;

对比

特性Vue 3 (setup)React FC (Hooks)
逻辑复用组合 API(自定义组合函数)自定义 Hooks
代码可读性逻辑集中,提升可读性Hooks 易于拆分和管理
生命周期管理提供组合 API,直观通过 Hooks 处理(如 useEffect

5 总结

特性Vue 3 (setup)React FC
状态管理refreactive 提供响应式状态useState 提供非响应式状态
数据流propsemits 实现单向/双向流props 和回调函数实现单向流
依赖注入内置依赖注入,适合祖孙组件通信使用 Context API 实现全局状态
组件管理和逻辑复用组合 API 更灵活且可读性强Hooks 易于拆分逻辑,但有时复杂

选型建议

  • Vue 3 更适合那些希望简化组件逻辑和状态管理的开发者,特别适用于中小型项目或希望以更加响应式的方式管理状态的场景。但并不是说vue3无法开发大型项目。
  • React 更适合大型项目,特别是具有复杂交互逻辑、需要深度拆分逻辑和复用组件的场景。(目前vue3的jsx还是有些gap的,后续章节我会说明下)React 的生态系统广泛,适合团队协作和长期维护
  • 国内政企项目推荐vue3,毕竟有点优势,vue2也够用,但上2.7版本得谨慎。
  • 个人项目随意,建议交叉混用,以便训练思维,如果比较急就挑顺手的吧
  • 对外项目,比如跨境、港澳合作以及面向国外团队,选择react会有优势,毕竟react的外部生态更庞大,又有大公司背书,这个主要是一信任度的问题,尤其是fb的开源做的真不差

最后,通过二者兼修(甚至多修svelte-angular等),尝试找到适合自己的开发模式,找到合适的状态管理(我选了rxjs作为中间层),剥离出UI和状态,后续我会介绍一些实践经验。


http://www.ppmy.cn/news/1534196.html

相关文章

Spring Redis 使用总结

1.简介 Spring中常用Redis做数据库的缓存&#xff0c;第一次查询走数据库并缓存到redis&#xff0c;第二次查询由redis直接返回数据。 2.安装Redis mac安装&#xff1a; brew install redislinux安装&#xff1a; sudo apt-get install lsb-release curl gpg curl -fsSL …

【CSS】兼容处理

兼容前缀兼容查询 由于不同浏览器对CSS标准的支持程度不同&#xff0c;可能会导致在不同浏览器中出现样式差异。为了解决这个问题&#xff0c;需要采取一些措施来提高CSS的兼容性 兼容前缀 兼容前缀针对的浏览器-webkit-WebKit 内核浏览器&#xff0c;如&#xff1a;Safari 、…

#git 问题failed to resolve head as a valid ref

问题如下&#xff1a; 解决方法&#xff1a; 1、运行 git fsck --full 可以查看具体error信息&#xff0c;一般都是head索引问题 2、.git\refs\heads\xxx&#xff08;当前分支&#xff09;txt编辑器打开显示乱码&#xff0c;而不是hash编码 3、在.git\logs\refs\heads\xxx&a…

【代码随想录Day29】贪心算法Part03

134. 加油站 题目链接/文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;贪心算法&#xff0c;得这么加油才能跑完全程&#xff01;LeetCode &#xff1a;134.加油站_哔哩哔哩_bilibili class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {// 创建一…

基于深度学习的不遗忘训练

基于深度学习的不遗忘训练&#xff08;也称为抗遗忘训练或持久性学习&#xff09;是针对模型在学习新任务时可能会忘记已学习内容的一种解决方案。该方法旨在使深度学习模型在不断接收新信息的同时&#xff0c;保持对旧知识的记忆。以下是这一领域的主要内容和方法&#xff1a;…

OpenCV-图像拼接

文章目录 一、基本原理二、步骤三、代码实现1.定义函数2.读取图像3.图像配准&#xff08;1&#xff09;.特征点检测&#xff08;2&#xff09;.特征匹配 4.透视变换5.图像拼接 四、图像拼接的注意事项 图像拼接是一种将多张有重叠部分的图像合并成一张无缝的全景图或高分辨率图…

JAVA并发编程高级——JDK 新增的原子操作类 LongAdder

LongAdder 简单介绍 前面讲过,AtomicLong通过CAS提供了非阻塞的原子性操作,相比使用阻塞算法的同步器来说它的性能已经很好了,但是JDK开发组并不满足于此。使用AtomicLong 时,在高并发下大量线程会同时去竞争更新同一个原子变量,但是由于同时只有一个线程的CAS操作会成功,…

Mac中访达显示/关闭隐藏文件

Mac中访达显示/关闭隐藏文件 您可以使用特殊的键盘快捷键查看 Mac 上的所有不可见项目。下面是具体步骤&#xff1a; 1、激活 Finder 应用程序&#xff0c; 打开可能包含此类文件的文件夹。 Command Shift 句点 【CMDShift.】3、如果您想再次隐藏文件&#xff0c;请再次重…