百科问答小站 logo
百科问答小站 font logo



Vue 和 React 的优点分别是什么? 第1页

  

user avatar   evanyou 网友的相关建议: 
      

这个问题下面的很多回答太偏激了,其实我淡出知乎就是因为这类破事... 但是作为作者还是认真地说一说吧,希望能以后别再有这种问题了。

这里我可以大方地承认,如果多年以后要论历史地位,React 肯定是高于 Vue 的。事实上,我作为一个开发者,也是由衷地佩服 Jordan Walke, Sebastian Markbage 这样的,能从开发模式层面上提出突破性的新方向的人。

React 从一开始的定位就是提出 UI 开发的新思路。当年 Pete Hunt 最开始推广 React 的时候的一句口号就叫 "Rethinking Best Practices",这样的定位使得 React 打开了一些全新的思路,吸引了一群喜欢折腾的早期核心用户,并在这个基础上通过社区迭代孵化出了许多今天被 React 开发者当作常识的 pattern。这是 React 伟大的地方,Vue 里面也有很多地方是直接受到了 React 的启发。React 敢做这样的尝试,是因为它是 Facebook。这样的体量的公司,在 infrastructure 层面获得质的提升,收益是巨大的,而且 Facebook 的工程师们足够聪明又要靠工资吃饭,改变他/她们的习惯并不是什么问题。而对外推广,则是一种大公司才有的 “改变业界” 的底气。

Vue 从一开始的定位就是尽可能的降低前端开发的门槛,让更多的人能够更快地上手开发。我以前也说过,开发 Vue 的初衷不是为了搞个大新闻,只是做了个我自己用得舒服的框架。我虽然也在 Google 这样的大公司呆过,但骨子里是一个喜欢自由的人,也一直觉得独立开发者很酷(这也是为什么最终自己也成了一个独立开发者)。很多时候我更希望自己做的东西能帮到那些中小型企业和个人开发者。举个例子来说,美国传统行业里有很多 small business,它们不像大公司那样有专门的 IT 团队来信息化整个流程,很多只能雇一个普通的 contractor 程序员,有些甚至是老板自己兼职研究代码。我收到过好几封这样的感谢信,说因为 Vue 让它们多快好省地做了个内部应用,解决了实际问题,这样的故事是让我觉得特别爽的。

做 React 这样的不迎合用户,而是试图改变用户的设计需要有足够的本钱:你得有足够的资源和背景去强行越过初始推广的那个陡坡。事实上,如果没有 Facebook 作为 React 的推广者,React 很可能最终是一个有着忠实用户群体的小众框架(比如 Elm)。作为一个个人项目的 Vue 没有这样的宣传资源,也并不是为了改变用户。所以从设计的角度上来说,Vue 首先考虑的是假设用户只掌握了 web 基础知识 (HTML, CSS, JS) 的情况下,如何能够最快理解和上手,实现一个看得见摸得着的应用。

一个 API 看得顺不顺眼,用得舒不舒服,很大程度上取决于你跟一个技术的核心用户群体的重合程度。编程语言之间喷来喷去还少么?大家都是图灵完备,然而此之蜜糖,彼之砒霜。Vue 的 API 设计固然有可以商榷的地方,但 React 也不是完美无瑕,不然也不会从 mixins 到 HOC 到 render props 一次次地折腾,更没有 hooks 什么事了。直到 Suspense 出现前,也不存在什么只有 React 才能做到的事情(顺带一提,有意思的是 hooks 基本上废掉了过去大部分基于组件的逻辑抽象模式,抹掉了 JSX vs. 模版的一个优势,也完全可以用在其他框架里,连 Angular 都已经有对应的原型实现...)然而 “不完美” 并没有妨碍在过去的几年内大量的用户用各自选择的技术做出实际的产品 —— 从 State of JS 近两年的数据来看,两者的满意率是差不多的,都在 90% 出头,说明两者在 “满足目标用户的需求” 这个衡量标准下,表现是差不多的。可维护性、可读性、优雅程度、生态这些东西嘴上怎么辩都可以,还是数据比较实在。

再说说具体技术层面:从加载速度、运行时性能来说,两者目前综合各种场景应该说是没有什么质的差别。硬要说的话,Vue 在 update 性能优化方面需要的心智负担可能少那么一点 —— React 如果不注意,容易导致过多的组件无用 diff,但是实际上真正会遇到性能瓶颈的应用也是少数... Vue 3 会比 Vue 2 快不少,加上模版编译还有一些可进一步发掘的优化空间,所以性能上会比现在的 React 有一定优势,但 React 那边也在研究基于 prepack 的编译时优化,这个也是挺值得期待的。Vue 3 对于 TS 的支持会有很大改善(包括 TSX),我们也在计划对模版做更好的 IDE 支持(比如补全、类型检查),现在没有不代表以后不能有,有批评我们改进就是了。其实过去大半年 Vue 本身没有什么大更新是因为精力都放在工具链上了,接下来又要回到核心上了。React 那边 time slicing / Concurrent mode 要明年 Q2 才稳定,那个时候应该 Vue 3 的 time slicing 应该也稳定了(原型已实现)。Suspense 在 data-fetching 稳定之前并没什么大用(要 2019 年中),这期间我们也会研究解决同类问题的方案。所以从纯技术层面来说,React 现在比 Vue 牛逼么?不好说。以后一定比 Vue 牛逼么?也不好说。

使用数量方面,有很多文章拿各种数据来比较,有的是 GitHub stars,有的是 npm 下载量,有的是 Google trends,有的是 StackOverflow 的问题数量... 其实这些数据都有很明显的问题,那就是它们跟实际使用者的数量并不一定是正比,会受到其它因素的影响,比如 GitHub stars 跟实际使用没有直接关联;使用者中使用 CI 的比例会影响 npm 的下载量;Google trends 很难完美过滤掉 React 这样的常见词汇的 false positive;文档和本身的上手难易程度会影响 StackOverflow 的问题数量,等等... 所以我自己一直是以 Chrome 开发者插件的使用者数量作为一个比较可靠的数据,因为它的关联度是最直接的,潜在的干扰因素也是最少的。目前 Vue 的开发者插件用户数量约为 70.4 万,而 React 是 136.3 万,大致可以作为参考。React 的使用量还是有明显优势,不过这个数字比起两年前已经很不一样了 —— 那时候大约是 1:7 的比例。从增速来看,Vue 是要快一些的。

说了这么多,无非是希望大家能停下来想想所谓的 ”A 技术比 B 技术牛逼“ 背后到底是在争些什么,我们使用这些技术的初衷又是什么。很多时候你说这方面,他说那方面,鸡同鸭讲,即使说到一起去,也往往缺乏对等的信息量或者基础共识,只是各自表达主观看法,最后变成两个阵营各自抱团取暖... 说到底,就算你证明了 A 比 B 牛逼,也不意味着你或者你的项目就牛逼了... 比起争这个,不如多想想怎么让自己变得更牛逼吧。


user avatar   lucas-hc 网友的相关建议: 
      

谢邀。这个问题其实已经不少人邀请过,在我的 timeline 上悬浮了挺久。为什么现在突然愿意回答一下呢?

2019 年已经行至年中,Vue 即将演进到 v3.0,刚刚过去的端午节 @尤雨溪 也做了 「State of vue 」的精彩分享;另一方面,React 到了成熟壮年期,hooks 等特性引领了未来发展趋势。

正好我上个月在上海 FD Conf 2019 做了一个主题为「React: the bad parts」的分享:FDCon2019 第4届中国前端开发者千人峰会 -百格活动。我的相关回答:React.js有哪些设计缺陷?

也巧,正在进行的「全球互联网架构大会」上,我分享主题「From Vue3.0 to React: Rethinking the best design」,对「Vue 对比 React」话题进行了粗浅分析。

记得 2013,Pete hunt 在推广 React 时,做了一个足以“颠覆前端开发”的变革演讲「React: Rethinking best practices」。目前来看,演讲中所带来的先进理念仍然是前端开发的“真谛”。但是有些细节和设计却应该随着时代发展而重新思考。尤其是再对比 Vue3.0 的情况下,也许能给我带来更多的启发。

2020 年了!!!我们是时候从更新的角度来 review 这个问题了!!!


我对一些老生常谈的话题不再赘述,比如:

  • Vue template 对比 JSX

我认为这只是「解决同一个问题的不同实现思路」,完全可以由开发者的个人偏好来决定。退一步讲,Vue 中也不是不可以使用 JSX;同样,JSX 也不是无法实现 Vue template 的特性,比如模版指令,我们完全可以从工程化的角度实现:

       render() {   const visible = true   return (     <div>       <div r-if={visible}>        content        </div>     </div>   ) }  render() {   const list = [1, 2, 3, 4]   return (     <div>       <div r-for={item in list}>         {item}       </div>     </div>   ) }      

当然,这需要我们基于抽象语法树 AST,实现解析模版指令的插件,思路也很简单:

相关代码我就不贴出来了,感兴趣的小伙伴可以找我讨论。

再比如,

  • Vue 和 React 实现复用

这个方面我觉得也没有复述的必要,因为在实现复用的道路上,Vue 和 React 都是经历了:Mixin -> Hoc(Vue 比较少用,模版套模版,有点奇怪了)-> render prop(Vue 有类似思想的实现为 slot) -> hooks(Vue3.0 function based API)

在这方面,UI 层面的复用本身不是问题:因为组件化本身就是天然可组合的。重要的是逻辑复用:hooks 和 Vue3.0 function based API 的设计无疑是最先进的,它将逻辑复用和组件表达在一定程度上解耦,避免了“面向生命周期编程”的困扰。顺便达到了更好的组合性和 TS 友好性。


我真正想深入的是这些方面:

  • Vue 和 React 的核心差异,以及核心差异对后续设计产生的“不可逆”影响
  • Vue 和 React 在 API 设计风格和哲学理念(甚至作者个人魅力)上的不同
  • Vue 和 React 在工程化预编译构建阶段,AOT 和 JIT 优化的本质差异和设计


第一点,首先我想明确一下:用 Evan you 的话说:双向绑定是对表单来说的,表单的双向绑定,说到底不过是 value 的单向绑定 + onChange 事件侦听的一个语法糖。这个并不是 React 和 Vue 在理念上真正的差别体现。同时,单向数据流不是 Vue 或者 React 的差别,而是 Vue 和 React 的共同默契选择。单向数据流核心是在于避免组件的自身(未来可复用)状态设计,它强调把 state hoist 出来进行集中管理。

真正我认为 React 和 Vue 在理念上的差别,且对后续设计实现产生不可逆影响的是:Vue 进行数据拦截/代理,它对侦测数据的变化更敏感、更精确,也间接对一些后续实现(比如 hooks,function based API)提供了很大的便利。这个我们后面会提到;React 推崇函数式,它直接进行局部重新刷新(或者重新渲染),这样更粗暴,但是更简单,让我们的开发回到了上古时代,就是刷新呗,前端开发非常简单。但是 React 并不知道什么时候“应该去刷新”,触发局部重新变化是由开发者手动调用 setState 完成。

React setState 引起局部重新刷新。为了达到更好的性能,React 暴漏给开发者 shouldComponentUpdate 这个生命周期 hook,来避免不需要的重新渲染(相比之下,Vue 由于采用依赖追踪,默认就是优化状态:你动了多少数据,就触发多少更新,不多也不少,而 React 对数据变化毫无感知,它就提供 React.createElement 调用已生成 virtual dom)。
另外 React 为了弥补不必要的更新,会对 setState 的行为进行合并操作。因此 setState 有时候会是异步更新,但并不是总是“异步”,具体可见我之前的回答:

在设计上,这给开发者带来了额外的“心智负担”,也引出了一些潜在问题(我把它叫做 React-helmet 门(我编的),有机会再展开)。再次赘述,Vue 的响应式理念,进行数据拦截和代理中不存在类似问题(当然也有 batch 的操作)。

这个设计上的差别,直接影响了 hooks 的实现和表现。

React hook 底层是基于链表(Array)实现,每次组件被 render 的时候都会顺序执行所有的 hooks,因为底层是链表,每一个 hook 的 next 是指向下一个 hook 的,所以要求开发者不能在不同 hooks 调用中使用判断条件,因为 if 会导致顺序不正确,从而导致报错。如下代码会报错:

相反,vue hook 只会被注册调用一次,vue 之所以能避开这些麻烦的问题,根本原因在于它对数据的响应是基于响应式的,是对数据进行了代理的。他不需要链表进行 hooks 记录,它对数据直接代理观察。

但是 Vue 这种响应式的方案,也有自己的困扰。比如 useState() (实际上 evan 命名为 value())返回的是一个 value wrapper (包装对象)。一个包装对象只有一个属性:.value ,该属性指向内部被包装的值。我们知道在 JavaScript 中,原始值类型如 string 和 number 是只有值,没有引用的。不管是使用 Object.defineProperty 还是 Proxy,我们无法追踪原始变量后续的变化。因此 Vue 不得不返回一个包装对象,不然对于基本类型,它无法做到数据的代理和拦截。这算是因为设计理念带来的一个非常非常微小的 side effect。从 Evan you 的截图中,我圈了出来:

简单说一下我个人的看法:事实上,Mobx 在 React 社区很流行,Mobx 采用了响应式的思想,实际上 Vue 也采用了几乎相同的反应系统。在一定程度上,React + Mobx 也可以被认为是更繁琐的 Vue。所以开发者习惯组合使用它们,那么(也许)选择 Vue 会更合理。

再来思考,Mobx 的流行也许也从侧面说明到底什么样的设计可能是更现代化的设计。


第二点,在设计哲学上。我认为 Evan you 很好地体现了中国人 humble 和 modest 的优良品质(开玩笑~),我选取了比较具有代表性的事件系统:

• React 事件系统庞大而复杂。其中,它暴漏给开发者的事件不是原生事件,是 React 包装过合成事件,并且非常重要的一点是,合成事件是池化的。也就是说不同的事件,可能会共享一个合成事件对象。另外一个细节是,React 对所有事件都进行了代理,将所有事件都绑定 document 上。请读者仔细体会下面的代码:

你告诉我他们的输出值好不好?

  • 另外,React 中事件处理函数中的 this 默认不指向组件实例。我就懒得再细说这个了。
  • Vue 事件系统我不多讲,大家看图:
  • 当然 Vue 事件处理函数中的 this 默认指向组件实例。连源码都写的那么“清晰易懂”

简单说一下我个人的看法,从事件 API 上我们就能看出前端框架在设计的一个不同思路: React 设计是改变开发者,提供强大而复杂的机制,开发者按照我的来;Vue 是适应开发者,让开发者怎么爽怎么来。


第三点,预编译优化问题。这个非常值得深挖,但是回答内容已然这么长了,我简单来讲吧。

Vue3.0 提出的动静结合的 DOM diff 思想,我个人认为是 Vue 近几年在“创新”上的一个很好体现。之所以能够做到动静结合的 DOM diff,或者把这个问题放的更大:之所以能够做到预编译优化,是因为 Vue core 可以静态分析 template,在解析模版时,整个 parse 的过程是利用正则表达式顺序解析模板,当解析到开始标签、闭合标签、文本的时候都会分别执行对应的回调函数,来达到构造 AST 树的目的。


我关心的是:React 能否像 Vue 那样进行预编译优化???

Vue 需要做数据双向绑定,需要进行数据拦截或代理,那它就需要在预编译阶段静态分析模版,分析出视图依赖了哪些数据,进行响应式处理。而 React 就是局部重新渲染,React 拿到的或者说掌管的,所负责的就是一堆递归 React.createElement 的执行调用,它无法从模版层面进行静态分析。

因此 React JSX 过度的灵活性导致运行时可以用于优化的信息不足。

但是,在 React 框架之外,我们作为开发者还是可以通过工程化手段达到类似的目的,因为我们能够接触到 JSX 编译成 React.createElement 的整个过程。开发者在项目中开发 babel 插件,实现 JSX 编译成 React.createElement,那么优化手段就是是从编写 babel 插件开始:

(这里我不再展开优化的原理和代码实现了,不增加额外的“心智负担”,感兴趣的同学可以关注我,或者关注 GIAC 全球互联网架构大会我的分享)

当然 React 并不是没有意识到这个问题,他们在积极的同 prepack 合作。力求弥补构建优化的先天不足。

Prepack 同样是 FaceBook 团队的作品。它让你编写普通的 JavaScript 代码,它在构建阶段就试图了解代码将做什么,然后生成等价的代码,减少了运行时的计算量,就相当于 JavaScript 的部分求值器。

我就用 Prepack 结合 React 尝了个鲜:

对比:

这不正是 React 梦寐以求的吗?

另外一个 React 的方向就是 fiber 时间分片了, @尤雨溪 说过(可能也是玩笑,说者无意,也可能是我没有幽默感,认真解读了):“React 是伤害已经造成,无法自身在预编译阶段做到更多,时间分片这样的优化只是在弥补伤害”。其实作为 React 的粉丝,这里吹了这么久 Vue,我发表一下我的想法:这反倒算是 React 多管齐下的一个做法。

最后,上一个借助 Babel plugin AST 实现一个类似预编译优化:remove inline functions 的小例子。

预编译后:


考量和设计一个前端解决方案的时候,向上扩展和向下兼容是非常重要的。Vue 向上扩展就是 React,Vue 向下兼容后就类似于 jQuery,渐进式有时候比革命性更符合时代的要求。

比如这个文稿页使用 React 渲染富文本生成的完整页面:

后端返回了富文本内容,过了几天产品的需求是实现:

添加笔记,且在划线高亮当前行后添加笔记内容,以及点击弹出动态 tooltip 等等。。。想想用 React 该怎么做,且做的符合 React 思想?

我不吐槽更多了:一个 React 粉丝向 Vue3.0 致敬!

— 于因天气原因而大面积航班延误被困在的深圳宝安机场




分享交流

我的课程:前端开发核心知识进阶

感兴趣的读者可以:

PC 端点击了解更多《前端开发核心知识进阶》

移动端点击了解更多:




  

相关话题

  jQuery为什么还在发布新版本? 
  如果 ElementUI 不维护了,也不再支持 Vue 3了我们该怎么办呢? 
  框架用比不用的真正优势? 
  为什么我觉得react这么难用? 
  react让我怀疑自己没有当程序员的天分怎么破? 
  框架用比不用的真正优势? 
  如果 ElementUI 不维护了,也不再支持 Vue 3了我们该怎么办呢? 
  react让我怀疑自己没有当程序员的天分怎么破? 
  如何评价 Vue 在 Github 上的 star 数即将超越 React ? 
  前端框架Stimulus的使用体验如何? 

前一个讨论
为什么现在的电脑应用程序这么吃内存(RAM)?
下一个讨论
有没有一个 PPT 技巧让自己觉得人生都亮了?





© 2024-12-22 - tinynew.org. All Rights Reserved.
© 2024-12-22 - tinynew.org. 保留所有权利