coppyC / blog

个人博客,用issue 分享,记录关于前端,js 各种经验和奇淫技巧。欢迎star, watch。
74 stars 2 forks source link

[2019-07-24] 为什么我从vue转到了react? #9

Open coppyC opened 5 years ago

coppyC commented 5 years ago

前言

本次标题党了,本文并不是踩一捧一的文章,毕竟我也不希望两边的使用者吵起来,或者来喷我。 虽然转到react 后,我也很喜欢react,但我还是希望从客观上对比两者 给希望能给在这两个框架中有选择困难的人提供一些帮助。

实际上,我也算是vue很早一批使用的人了,在vue2.0刚出的2015年,那时我还是只听过angualrJs 的萌新,然后听说vue多好用多好用,什么既有angular的优点,又有react的优点。我一想,要学就要学最好的,少做一些无用功,然后就入了vue。但即使现在我会优先选择react,我也不后悔当初的选择,因为vue真的很容易上手,对新手十分友好,而且功能丰富,而且现在满大街的vue,也证明了我当初的眼光。那么问题来了,既然如此,那我为何还选择react?

初探react

第一次使用react的时候,大概是一两年前的事了吧。 只记得那时的天还很蓝,云还很白。。。扯远了。。 那时我已经用vue开发过很多个项目了,虽然我自认vue天下第一, 但总有一些自视甚高的人认为vue是新手才用的,为了证明他们是错的,我决定试用一下react 看完官网的内容,我发现react的内容很少,很快就看完了 第一次上手react,我就把它当vue来写 我是怎么把它当vue来写的呢,

用过react后,我以想react功能又少,写起来又繁琐,真不知道那些吹它的人有没有用过vue 后来用react写完我一个课程设计,再之后就没用过react了,vue天下第一的思想深深刻在骨子里。

再识react

有了使用react的经验后,我也自认知已知彼,认为vue浑身是宝,react比之只有不及。 一次偶然,打开知乎后,我听到了很多不同的声音(其实就是两个流派在吵架。。。) react这边的,无非就是 说什么vue太简单,又或者是什么vue不适合大型项目 vue这边的,无非就是 简单并不是缺点,也有问大型项目到底是什么需要,vue为什么不能用 这些一般就是只用过一个框架的人发表的言论,不过当中我发现了一些比较有价值的评论 是react用户吐嘈vue的

再探react

在那之后,我也认识到了vue的缺点,而且越是注意就越是难受

vue的一切都很棒,但在维护这一块,可能真的不是很容易,我尝试使用typescript来改善这一点,虽然vuef支持ts,但它似乎和vue不是很搭配,写起来不是很舒服。

在使用mpvue的时候,有一堆bug,但是mpvue团队也没有积极维护,那时就经常逛mpvue的issue,一堆人要摸索mpvue可能要凉凉了,这时就看到一个评论说,vue的项目大多最后都不积极维护,隔壁react的taro维护很积极(怎么有种在做广告的赶脚),然后我就跑到taro试一波水。taro的团队维护确实是很积极,在那时,已经做到了一份代码编译到各种平台的小程序,不止,还能编译至h5和react native,而且帮我们做了api兼容,现在回头看,taro的维护确实积极,那时已经支持了这么多平台,而mpvue那里还只支持微信的小程序,现在taro支持了react的最新语法hook,而mpvue还在用 vue-cli2的模版,不过已经支持小程序多平台编译。

说来也搞笑,我第一次真正体验react,居然不是原生react,是使用经过小程序语法限制的taro,taro的cli提供了很多的选项来创建脚手架,我选择使用typescript和mobx。那之后我也体验到tsx(typescript react)的魅力,正如网上说的那样,提示即文档,当然,这归功于typescript,但为什么和vue使用就没有这种体验?我认为是typescript支持了jsx,不支持什么模版引擎,react中推荐使用的是jsx,推荐使用模版引擎的vue想介入其中就很难。另外,vscode的官方就是用react写的,typescript的是微软的东西,所以在vscode写react应该是很棒的体验,不然他们自己不得难受死。

重识react

vue的作者也说过,

react本身依赖很多社区插件,只只却用react,我相信很多人是hold不住的

说的确实在理 (想起了第一次使用react写课程设计的我) react的强大,并不在于它的本身的功能,而在它强大的拓展性,这促使了它成为前端最为活跃的社区,这点是不用怀疑的,各种轮子和ui漫天飞,我也说过,单单一个状态管理,就有三种完全不同的解决方案,对比vue只有一个vuex熟为人知,确实是活跃,而且还有很多vue不曾拥有的优秀组件,像富文本框架,你可能会说,富文本有什么罕见的,注意,我这是说的不是富文本组件,是富文本框架,可以使用富文本框架来轻松写出定制化的富文本编辑器,比如什么在富文本里面内置个vim什么的[#滑稽],而且这样的框架有两个,slate和draft,两者均基于react。

不过纵然有这么多优秀插件,react比起vue仍有不足之处,比如react+mobx是繁琐版的vue,毕竟第三方实现的,整合度远没有内置实现的高。

不过我写了一个库来增加react+mobx的契合度(参考了vue的ts class版本),让react写起来就和 vue一样,甚至还更舒服 (该库已停止维护并不打算发布,因为该库为 class 组件设计,但现在我已经全部组件使用函数组件+hook来编写组件) 这个库目前还没有开源,因为我在搞另一个大pro,还没来得及写文档。 * 这个库的功能有 自动观察数据,不用再setState * 自动按需绑定 this,不用再bind * 提供 双向绑定语法糖

心动了吗? 心动就催更啊

重返react

其实在转到react的之前,我一直在寻找一个理由,因为vue真的在很多场景开发起来更快更舒服,特别是在表单密集处,尤其是双向绑定减少了不少重复码字,但最后打动我的只有一个,那就是vscode的亲儿子--typescript,与react的完美契合度,用过之后,就再也回不去了。 但在入了react之后,我发现react其实有很多地方在打动我:

  1. 强大的社区,数不尽的解决方案,还有蚂蚁的antd 全家桶,蚂蚁团队维护的ui组件,十分之成熟,还送了一套antd pro管理端模版,以及无缝切入iconfont,axure和sketch的antd设计素材,一套流程,你要的这是全都有。虽然去年antd的圣诞节彩蛋给antd抹了不少黑,但也提高了不少知名度,获得不少star,我就是那次知道了antd (#捂脸)
  2. 强大的拓展性: react本身就是js,没有太多的束缚,不像vue,一个.vue文件把条条框框给限制了,在react很流行的styled-component在vue却流行不起来,这就是react易拓展的优点,也使社区百花齐放
  3. 易于理解: jsx就是个语法糖,没有什么黑魔法,看着jsx,都能人脑编译出来jsx编译后的样子,但如果你给我vue的模版,我还真不知道,vue内置了很多黑魔法,很难窥探黑箱子里面的东西。由于在react中,一切皆js,所以,你只要一个劲学js,你的react就会变得很厉害,而vue则不需要太多的js技巧,相反,还要学习vue的语法 v-if,v-for 什么的,而react是用js本身自带的if,数组的map来搞,不需要学习新东西,这些都是js。
  4. 上面说到,react就是js,js本身就是很灵活,所以我才能写出前面说的一个小库提高react+mobx的舒适度,内置黑魔法。所以只要js足够好,就可以改造react来去掉上面说的一些react问题

最后说到hooks,vue也有,不过vue的hook是语法糖,本身还是对象,该有的生命周期也都还有。而react的hook是真的翻天变化,万能的this都没得用,各种生命周期也没有一一对应的方法,只有一个useEffect,我初探了一下,还是有点难适应过来。不过如果hook能推广成功,那社区也要洗洗牌了,像redux作为react的状态管理大佬位置可能就不保了,毕竟mobx和rxjs更加适应hook

推一篇 rxjs + hook的,看着都简洁(中间变量少到夸张) https://zhuanlan.zhihu.com/p/50921147

再给点react学习的推荐吧

我现在的react栈是 react + mobx + styled-compnent + antd + typescript

结语

实际上,两者都是很棒的框架 可以的话,两者都学(毕竟有时候要接手别人的项目,技多不压身)

曾经,我给很入门前端的人推荐vue,如果时间可以重写,历史可以改写,我会选择vue, again. vue内置了很多语法糖,模版引擎给了不少省心的优化,而且易于上手,关键是没有使用社区力量的react完全打不过vue,使用社区的react对折腾成本过高,学习曲线陡,不适合入门。

lesonky commented 5 years ago

都是工具而已,需要什么就用什么,当然,精通一个也是必要的.

个人感觉 vue 是自动挡的车,最佳实践都是官方维护,不纠结,油门一踩就上路 react 是手动挡的车,啥都要自己来,油离配合,档位控制,有操控乐趣. 有人说手动挡的省油啊,但是对于大多数人来说,真不省油,因为技术不高.操控乐趣什么的,一上坡道就熄火也是有的,能跑起来就已经拼尽全力,谈什么乐趣.手动操控的乐趣大概只属于高手

从vue入react还是有不少阻力的,需要将原来自动处理的东西,自己手动设置一遍,虽然可以添加自己的黑科技代码在里面,但是大多数时候,感觉,真是好啰嗦,可能会被新的hooks功能吸引到,但是实际生产中,并不会用太多,因为大多数的数据都是业务的,根本也没有复用的需求,慢慢的,发现以前一个指令干的事情,到了react里面变成了一堆雷同的代码,直到有一天,在这堆雷同的代码中加入了自己的黑科技代码,处理了一个棘手的需求,才能自我安慰一下,还好用了react,要是vue,这个需求可就不好做了......

从react入vue,会发现vue真好用,一把梭.vuex真好用,条理清晰,redux什么的处理个异步还要加个 saga...,自动监听真简单,折腾半天mobx,不如直接上vue.事件监听也不错,不用bind来bind去,react里面的很多高级技巧,到了vue,变成了一个简单的语法糖,真的声明式编程,叫你干啥就干啥,油门一踩,风驰电掣.直到有一天,遇到了一个神奇的bug,然后不知道哪里错了,艾玛,这东西到底是怎么跑起来的,要是react就好了,至少这些逻辑都是我自己写的,还能看看,现在傻逼了,ε=(´ο`*)))唉.......

对于大多数人来说,自己的代码性能并不会比vue提供的自动化逻辑优秀,所以vue省心又好用.但是涉及到高级的技巧,也是要深入研究的,也就是说 vue 简单用用也可以,复杂使用也可以,起步低,进阶知识可能等到你使用了几个月之后才可能会需要. 而react是就算你想简单用用,你也要学习一堆玩意,要不然根本跑不起来,起步高,进阶起来就天马行空了

等两个架子都用习惯了,发现,殊途同归,一种车开久了,总会厌倦的,换着开开,体会不同的乐趣吧

coppyC commented 5 years ago

@lesonky 说的在理,两个框架都很不错,在有react的时候,vue能火起来,也说明vue在它的优势所在,而react不vue的反击下,仍然坚挺,也说明它仍有可取之处。

xiaodun commented 5 years ago

大佬有什么Vuecli3.0 + ts的文章推荐吗,遇到好多坑,以为官方都出了,这波稳了,没想到,,,,

或者是我有什么基础的东西没掌握到,,,

coppyC commented 5 years ago

@xiaodun 首先说明一点,cli3和typescript没有关系,cli只是初始项目的工具,提供一些hello world模版。

然后我可以理解成你是在vue+ts使用上遇到问题而不是cli+ts。这个问题,其实我认为ts和vue的契合度不是很高,从vue+js转到vue+ts,并不能带来很大的质变,因为ts不擅长处理vue的模版,还有vue各种循环性,更改this,让ts很难自动做类型推断。导致在ts大行其道的情况下,vue+ts的组合才特别少见。这也是我转react的一个原因,毕竟ts是主动去支持jsx,而vue是在努力支持ts,太被动了。不过听说vue3采用hook,对ts的支持会更好,而且vue本身也要采用ts重写,到时候可能用ts写vue的人会更多。vue2+ts可以看看我的第一篇博客,有提到一些,最佳实践后并发现没有比写vue+js好用很多

说说ts,不知道你遇到什么坑,在我认为,ts就是增强提示,提高可维护性的,把类型设为any后,又和js一样,不会有任何类型错误,但这样也失去ts的价值。最近看到一篇不错的ts文章,可以看看。 https://juejin.im/post/5da048e2e51d4578477a671e

xiaodun commented 5 years ago

@xiaodun 首先说明一点,cli3和typescript没有关系,cli只是初始项目的工具,提供一些hello world模版。

然后我可以理解成你是在vue+ts使用上遇到问题而不是cli+ts。这个问题,其实我认为ts和vue的契合度不是很高,从vue+js转到vue+ts,并不能带来很大的质变,因为ts不擅长处理vue的模版,还有vue各种循环性,更改this,让ts很难自动做类型推断。导致在ts大行其道的情况下,vue+ts的组合才特别少见。这也是我转react的一个原因,毕竟ts是主动去支持jsx,而vue是在努力支持ts,太被动了。不过听说vue3采用hook,对ts的支持会更好,而且vue本身也要采用ts重写,到时候可能用ts写vue的人会更多。vue2+ts可以看看我的第一篇博客,有提到一些,最佳实践后并发现没有比写vue+js好用很多

说说ts,不知道你遇到什么坑,在我认为,ts就是增强提示,提高可维护性的,把类型设为any后,又和js一样,不会有任何类型错误,但这样也失去ts的价值。最近看到一篇不错的ts文章,可以看看。 https://juejin.im/post/5da048e2e51d4578477a671e

@coppyC 主要是配置和代码提示这些,并不影响代码运行,但是影响编程体验, 即便是不加ts,在你文章提到的诸如 "加后缀后有什么好处?"这种也未曾体验过

cli3 之后我在vue文件中使用原生的事件类型得不到提示,但是在ts的文件中却可以,

还有我想全局提供lodash,不必要每次都import一下,但是打包的时候却不能只打包使用过的函数, 类似这样的问题令我困扰,我感觉自己用早了。

coppyC commented 5 years ago

@xiaodun 可能是我太菜了,不太能理解你在说什么。如果是vue的提示消失的话,我倒是遇到过几种情况,一次是添加原生vue没有的选项,导致提示消失,有的时候是没注意,在一个文件写了两个script,其中一个就会没有提示,这种可能是你说的第二个问题。这些主要是vue的提示全由一个对象开始,且类型十分复杂,稍微解析出现错误,可能整个vue文件的智能提示就没了。

至于最后一个问题也和ts没关系啊,完全是webpack的按需加载依赖,全局引入自然就会全部被打包,按需引入自然要写多点代码。 不巧的是,vue提供了原型链,还推荐把全局的东西挂上去,而且很多ui库用vue加载插件的方式,帮你把全部组件全局加载,这导致在vue按需加载很难,这不是vue的错,但vue至少是帮凶。

xiaodun commented 5 years ago

@xiaodun 可能是我太菜了,不太能理解你在说什么。如果是vue的提示消失的话,我倒是遇到过几种情况,一次是添加原生vue没有的选项,导致提示消失,有的时候是没注意,在一个文件写了两个script,其中一个就会没有提示,这种可能是你说的第二个问题。这些主要是vue的提示全由一个对象开始,且类型十分复杂,稍微解析出现错误,可能整个vue文件的智能提示就没了。

至于最后一个问题也和ts没关系啊,完全是webpack的按需加载依赖,全局引入自然就会全部被打包,按需引入自然要写多点代码。 不巧的是,vue提供了原型链,还推荐把全局的东西挂上去,而且很多ui库用vue加载插件的方式,帮你把全部组件全局加载,这导致在vue按需加载很难,这不是vue的错,但vue至少是帮凶。

今天早上有折腾了一通,不知道折腾了什么,提示、跳转竟然有了 现在只能把插件 配置啥的复制一遍,回家里试试 果然需要多多于其他人交流!

关于按需导入的问题,我不是很理解你说的,即便是在开发时候全局提供了,但是在打包的时候,插件在分析语法树的时候只打包用到的api应该能做到,何况lodash本身也提供了模块化的功能,我认为是插件之间的配置没有搞对,过些日子在研究下。

coppyC commented 5 years ago

webpack 的 Tree Shaking (按需引入) 其实借鉴了 rollup (应该是最早能按需引入的打包工具) 的tree shaking

rollup的tree shaking规则 是这样的,可以参考一下, https://www.rollupjs.com/guide/introduction/#tree-shaking

另外,还要检查你的webpack有没有开启Tree Shaking,一般都开启了。

webpack 的是这样介绍的 https://www.webpackjs.com/guides/tree-shaking/

主要是 import 写法,不知道你是怎么写,可以参考一下这个例子

// 按需引入 lodash 的 concat
import {concat} from 'lodash'
concat(array, 2, [3], [[4]])

// 引入整个 lodash
import _ from 'lodash'
_.concat(array, 2, [3], [[4]])

所以我才说按需引入会麻烦一点

Mrcxt commented 4 years ago

本来都想开喷了哈哈,结果看下来发现写的真的很透彻,双方的优缺点都写的很清楚。 我本身也是写vue的,但是我真的很羡慕react的生态啊,很多好东西vue生态上虽然有,但是质量上还是有差距。 可是我是真的受不了jsx啊哈哈,还有className这个属性命名。再者vue的css解决方案真的很棒,react上面的css方案还是有所欠缺啊。 不过呢学还是要学的,不多学点怎么涨工资呢哈哈

coppyC commented 4 years ago

@Mrcxt 表现出我极强的求生欲 [#滑稽]

jerry000lin commented 4 years ago

博主你好,因为新项目用 antd 的缘故,我也正在从 vue 转到 react 想问下博主新项目的话用 hook + mobx 的是否是用 mobx-react-lite 这个库,或者说还有别的方式? 另外有没必要一并使用 mobx-state-tree ,不清楚 mobx-state-tree 除了时间旅行还提供了别什么?

coppyC commented 4 years ago

@jerry000lin 你好,如果用mobx,装mobx和mobx-react就可以了,mobx-react已经包含了mobx-react-lite,当然,你如果全部用hook,不用class 组件,装 mobx-react-lite 也行。 值得一提的是,mobx-react-lite 的 README 文档内容有些落后,示例还写着废弃的api useObservable,而现在官方推荐使用的是 useLocalStore,文档的话,建议看这个比较新,不要看 README.md 的

至于mobx-state-tree ,我没有使用过,不好意思,不能帮到你,mobx-state-tree 虽然提供了更加牛逼的功能,但我用mobx本来就是图个简单快捷,结果 mobx-state-tree 把它搞复杂了,而且大部分人实际开发都用不到这些功能,如果你真的需要很复杂的功能,可以试试redux-saga,这货能提供了很多很似很牛逼,但一般都用不上的功能。不过可以得出结论,mobx-state-tree 不是一定要搭配 mobx 使用的。

另外我新react 项目不怎么使用 mobx 了,因为 mobx,又要写 observable,而且每次还要在外部包裹一个observer,其中,只要少做一步,就出bug,特别是 observer 总是忘记写。所以我自己写了个简单的状态管理,https://github.com/coppyC/mobx-hook, 如果你从vue过来的话,这个写法可能会比较亲切,把 useData 想像成 vue 的data,然后什么都信里面塞,完事。不过,我这个包在局部状态写着舒服,在全局状态管理方面功能就不及前面提的那些了,也没有提供什么牛逼的功能。个人维护的小包,小项目还可以试试水,大项目慎用哟。 ps: 虽然包名叫mobx-hook,但和mobx一点关系也没有,只是因为最初的 0.x 版本和 mobx 有点关系。

另外,为什么这些 全局状态管理都提供了这么多复杂的功能呢? 我觉得主要的原因就是,全局变量都是魔鬼,一但出bug,就很难调试,所以,我的做法是,尽量少写全局变量,而不是去使用很复杂的全局状态管理。

哦对了,antd也有vue版本,虽然不是官方维护的,但如果你真的很喜欢vue,没有必要专门为了antd而去使用react呀。

BoBoooooo commented 4 years ago

vue3: react最佳实践 逃);

xmsz commented 4 years ago

我和楼主一样差不多14年先接触Vue,然后一直到现在,期间也经历了非常相似的事情。

不过我现在相当于是第三个阶段的选择期

第二个阶段选择期就是Vue@2.x和React相比,Vue确实不太好维护,各种黑盒处理,导致了其他很多不好的影响。

然后也是同样的学习了React然后使用过Taro,但内心还是更喜欢Vue,而不是React。因为我的优先顺序是利用UI框架 + 加上自己的设计思路 = 一个成熟的解决方案 而UI框架上,如果使用React,那前期的路确实很长,而且强迫症我会想要真正熟练使用,那就真的时间不够。

讲到这里,我的建议就是开始的时候还是学习React好,因为你的目标是实现一个成熟的方案去服务业务,而不是仅仅提高了自己的开发舒适度和速度


经历第二个阶段确实非常迷茫,因为那时候已经看到头了,就是以后肯定要换成React,但是现在实在没有时间。 特别其中一点也是文中说的关于维护,团队开发最麻烦的就是你不一定能看懂别人到底在写什么?特别是在使用Vue的过程,各种Mixin,this啥的,你根本不知道这些是啥,会有什么影响,能不能改。就算是自己写得,以后回过头可能都忘记这是什么了?


而另外一个原因就是跨端开发,也是开始接触小程序的时候,mpVue也好uni-APP也好这种野路子团队做出来的东西,能跑起来已经万幸了,更别说加了更多的黑盒处理...而市面上也没有更好的方案。

所以那时候我决定web端和小程序端分离,小程序端单独写构建,然后参考Taro加入了JSX的支持。当然TypeScript肯定少不了。 这样在小程序端确确实实实现了和Vue一样的开发舒适和项目管理。

但面临的坑更多了,特别是JSX要实现编译成小程序的代码,不仅限制多还容易出问题。而且还不能进一步优化。

而且这始终不是个好办法... 只是临时补救一下,当然并不只是Vue这样,Taro@2.x的版本也一样,只是社区比较活跃而已。

直到运行时编译的方案被用到了小程序上,就是kbone和Taro@3.x的方案。这个方案用上以后,解决一个大问题就是小程序端+web端真跨端开发。再也没有什么限制,也不要求一定要Vue或者React。

然后看到这,实际上问题就剩下一个那就是Vue本身的问题,黑盒太多的问题。

然后奇迹又发生了... vue@3.x版本发布了

我的天,vue@3.x的特性直接解决了剩下的所有问题。我们团队用了半年了,目前来说没有任何问题,开发速度快,代码review可行,写得代码可维护也清晰可以说没有任何管理上的问题。所以再大的项目都能处理。而且写起来还是很快,但这次的快没有任何黑盒的代价。而且从设计模式上,实现起来很快

在这个阶段,Vue@3.x可以说确确实实做得非常好,而且已经没有什么之前说的问题了。

所以我们讨论的是 vue@3.x + 运行时编译跨端方案 与 React的对比了,因为Vue@2.x的方案确确实实问题很多。


看到这,其实也告诉Vue开发者柳暗花明了。Vue的方案完完全全和可以和React旗鼓相当,比不过的只是生态和社区(当然差距并不是大到赶不上)


第三个阶段

而第三个阶段是真移动端全覆盖问题

iOS和Android端其实都是属于客户端,而且以后肯定都是前端范畴。

而iOS和Android端最好的方案还是Flutter,那这样代码又分开了。。。又要维护多处代码

而目前的全平台方案其实上和小程序端早期阶段一样。还是使用编译时方案,所以开发体验很差。 并且Vue也有全平台方案,但React相关的工具比较成熟,特别还有React-Native这种别人已经填了很久的坑。所以首选还是React

这时候又陷入了选择,就是又要等到运行时方案出来,还是就现在放弃Vue。和第二个阶段简直一模一样。

事实上,阿里的Rax已经做出来了真全平台的解决方案,web + 小程序(同时支持运行时和编译时) + iOS/Android(基于Flutter实现,自己多了一层胶水代码)


在这个阶段,我们考虑选择的因素就剩下时间成本了。 Rax方案全部开源以后,Rax + Vue肯定很快就有了。但这个时间点不得而知。


最后如果是初学者还是建议先学自己一步一步来,到UI框架阶段先选着React,然后选择Vue@3.x(仅学习实现方案)。这样的话一劳永逸。

superestze commented 3 years ago

我最先接触的是aurelia, aurelia的作者曾经是angualr的作者之一, 后来在学的angular, 学完了以后, 发现vue和react使用很不习惯, 尤其是用起来rxjs在vue和react中并不如angualr流畅。

zhoufanglu commented 3 years ago

我还在楼主的第一个阶段,真的是绝对react难用,但是他一定好,因为大厂都在用,下定决心重新再学习。