20年07月写的,从内网搬过来
Vue和React之间存在的差别并不会太过巨大,因为本质上两者都是MVVM的方式。同时也存在很多相互借鉴的地方。但是想要完全的将自己Vue上的经验迁移到React当中去,还是需要去完整的学习文档和动手实践。而这篇文章的目的也仅仅是提供一个迁移的思路,如何从Vue到React依然需要你自己的摸索。
Vue和React的设计思想区别
Vue模板,命令,配置完成页面。
react 函数,映射成页面。
本质的目标不同,
Vue 从一开始的定位就是尽可能的降低前端开发的门槛,让更多的人能够更快地上手开发。(低难度高速度)
React 提出一个新的UI开发思路。(声明式,高可维护)
你可以从各自双方的官网中声明的特性看出一些端倪。
jsx和模板
jsx和模板其实没有太大的区别,只是jsx的代码可以更零碎的分布在各个地方。能够作为参数在函数,组件之间传递。而模板则是更加完整的一块写有预设指令的html(实际上Vue也提供了render props类似的方法 slot组件)。
jsx当中由js环境转向html用()括号括起来,里面就可以写html了。注意和vue里面一样 里面只能有一个根标签。类似于vue的temp标签,react当中可以使用React.Fragment标签也可以用<>>简写形式。在html中可以通过{}标签来转到js环境。
模板的优点:简单组件的高可读性。
对于vue,一般的组件你可以很迅速的了解他的结构大概是个什么样子,同时vue单文件系统也将所有的信息都集中在了一个地方。
jsx的优点:良好的类型推断.
jsx的做法就是将dom放到了js当中去,因此他也能提供更多了类型推断。
指令系统
值得注意的一点是:react当中并不提供指令系统,所以在Vue当中使用起来十分方便的各个指令在react当中都不能使用了。但是与此同时,你完全可以用js的语法来实现他们。而如何优雅的实现它们就是你的学习目标。
// vue
// react
arr.map((item,index)=>(
<>
{index==0?null:( )}
>
))
hooks
hooks是需要着重学习的一部分。hooks也是vue当中暂时没有的一部分(据说会在Vue3.x当中提供支持)。
在我的理解当中hooks像是react提供了一系列的工具,帮助你在渲染时做一些事情。而由vue转向react最大的不同就是,react无比关心渲染时发生了什么,而vue只关心数据的改变动作。(和网上说的不太一样,只是我个人学习感觉)
自定义的hooks,实际上是官方hooks的缝合怪。可以将一些公共逻辑提取出来。而自定义hooks和Vue当中直接写公用方法的区别就在于,hooks是会参与你的渲染过程的,而单纯的方法是没法参与的。
hooks的优点和vue做对比,就在于它把逻辑都放在了一块来说。而他的缺点也很明显,带来了很大的心智负担。
css的处理
react当中使用js来对css进行管理。可以直接在js当中导入css,通过className应用在jsx当中。
而Vue当中的css可以再vue单文件当中直接声明,并且配合scope属性让css只在当前文件生效。而react当中就需要webpack插件配合了。
单向数据
react和vue实现单向数据的原理也并不一样。
vue实际上也是单向数据,提供的双向绑定本质上是一个语法糖。
vue通过对数据的监听,当观察到数据产生了改变则去对新的v-dom和旧v-dom进行对比再去更新UI。
react中数据的更新主要是通过setState和props的改变来触发的。触发了之后会通过对应的render函数来获取新的renderElement树然后和旧的element树diff比较更新实际dom。
这就导致了一些不同的地方,vue当中你可以直接去修改你的data数据,因为是一直在监听的,这都会触发你的UI更新。而在react当中你一定要通过setState才能触发UI的更新。这一点和Vue是很不相同的。
这也同样导致vue当中watch和compute属性对于react没有意义。因为react每次渲染都会触发render函数,你的计算依赖写在这当中就每次都会得到执行。
实际上vue当中watch和compute的区别有一点就在于compute是会缓存你的计算值的,而在react当中,你可以通过useMemo的hook来实现相同的缓存功能。
生态系统
从vue到react上非常不一样的一点还在于工具链的改变。两者对工具的态度也是不一样的。
vue官方提供了所需要的如路由管理,状态管理。而react则更加开放,都有丰富的实现。普遍来说react的社区生态要更好一点,而vue的中文生态要更好一些。
由于vue和react对工具链的态度不一样,所以两者官方提供的cli/脚手架也不相同。react提供的create-react-app并不会像vue-cli一样提供导入了vue-router,vuex的种子项目,而是只会提供一个基本的项目。但两者都同样选择把webpack配置隐藏了起来,只暴露出一个配置文件提供配置。 Vue-cli2.x直接将脚本都暴露在外,而在3.x的时候将其全部隐藏,仅提供一个配置文件让你可以覆盖默认配置。而CRA则默认隐藏,但可以使用命令将数据弹出
Suspense特性
Suspense 悬念。这也是一个目前react特有的一个组件(Vue3.x也会支持)。并且现在Suspense依然是处于实验阶段。
Suspense 让你的组件在渲染之前进行“等待”,并在等待时显示 fallback 的内容。(未来会加入通过Suspense进行数据获取)
当你在Suspense当中抛出一个未完成的Promise,会让Suspense先渲染你设置在fallback当中的内容。直到Promise完成,再渲染具体的内容。
值得注意的一点:使用Suspense如果你使用一个页面填充未完成的网络请求,你需要注意尽量在Suspense中不要包括不会改变的组件,因为这会使你的页面发生闪屏。(如果你没有用Suspense包住你网络请求的组件,那么这个Promise可能会被跑到最外层,引起闪屏。)
这里引起闪屏的原因在于,视觉上不变的组件会被认为是没有发生变化的。但是如果有Suspense包裹它,那么当其他组件的网络请求发生时,他依然会经历一次由静态组件->Suspense的callback->静态组件的过程。
route
react当中主要用的比较多的route框架就是react-router和react-router-dom了。实际上react-router-dom库是react-router的一个包装库,react-router只实现了路由的核心功能。而react-router-dom则在其基础上添加了许多实用的组件。
和vue不同的地方在于,react router中路由也是通过组件的方式进行编写的。于是他会是这样的:
当然你同样可以通过写配置然后转成这种写法。
在vue-router当中,通过在vue对象上挂载router对象来暴露各种操作的方法(Vue插件机制)。而在react当中,对于class组件他会通过props注入match等对象,而对于函数组件则提供了useParams,useMatch等hooks。
另一点值得尤其注意的地方在于在react-router当中如果你直接这样配置路由,那么当你访问的路由能同时匹配到多个path的时候,他会帮你同时渲染所有被匹配的路由组件。产生这种问题时,可以通过配置exact属性(精准匹配)或者使用Swich组件来解决。
react-router当中是从上到下去匹配路由的,这一点也需要注意一下。
数据管理
vue当中使用的数据管理的工具是Vuex,而在react当中则可以选择Reduce或者react-reduce。
实际上这三者之间的差异并不太大,vuex很大一部分也都是借鉴了reduce的设计理念,而其中最大的区别只是在于具体的使用之上。
而现在hooks出现了之后,实际上用useContext和useReduce组合替代Reduce的方案已经很普遍了。而另一边,vue3.0中hooks的出现也可能会取代vuex的位置。
碰到的疑惑
实际上技能迁移过来碰到的疑惑并不算多(可能是接触的react还不算深),但是也确实会有一些十分令人不解的地方。而最大的不解就来自于hooks。
hooks的设计确实很厉害,也解决了一直以来很多的问题。但是从原本Vue当中明确的生命周期跳转到react hooks这种每次状态发生改变都会运行函数一次,而hooks又会根据自己不同的特性发生不同的情况。
同时在react的官方文档当中,甚至会有很多警告,告诉你一个错误的使用会导致bug。也会告诉你,你的一些优化可能是负优化。这在之前vue当中是少见的。
总结
从vue到react的路,还没有走完。一些见解可能也比较肤浅。但是框架之间的对比,显然是很有意义的。兼听则明,偏信则暗。vue和react之间也一直存在着相互的借鉴。学习新的框架非常重要的一点就是知道什么是好的什么是不好的,而对比两个框架时非常重要的一点就在于知道什么时候什么是好的什么是不好的。