关于 Vue 和 React 区别的一些笔记 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lihongxun945
V2EX    前端开发

关于 Vue 和 React 区别的一些笔记

  •  
  •   lihongxun945 2018-07-26 09:27:10 +08:00 4026 次点击
    这是一个创建于 2684 天前的主题,其中的信息可能已经有所发展或是发生改变。

    转自我的博客,原文地址:https://github.com/lihongxun945/myblog/issues/21

    这篇文章记录我在使用 Vue 和 React 的时候,对他们的不同之处的一些思考,不仅局限于他们本身,也会包括比如 Vuex/Redux 等经常搭配使用的工具。因为涉及到的内容很多,可能下面的每一个点都能写成一篇文章,这次先简单做一个概要,等我有空做一个详细的专题出来。

    监听数据变化的实现原理不同

    • Vue 通过 getter/setter/ 能精确知道数据变化,不需要特别的优化就能达到很好的性能
    • React 默认是通过比较引用的方式进行的,如果不优化( PureComponent/shouldComponentUpdate )可能导致大量不必要的 VDOM 的重新渲染

    从这一点来说,我认为 Vue 的实现方式要比 React 来的更好更智能一些。

    数据流的不同

    vue-react-data-flow

    大家都知道 Vue 中默认是支持双向绑定的。在 Vue1.0 中我们可以实现两种双向绑定:

    1. 父子组件之间,props 可以双向绑定
    2. 组件与 DOM 之间可以通过 v-model 双向绑定

    在 Vue2.x 中去掉了第一种,也就是父子组件之间不能双向绑定了(但是提供了一个语法糖自动帮你通过事件的方式修改),并且 Vue2.x 已经不鼓励组件对自己的 props 进行任何修改了。 所以现在我们只有 组件 <--> DOM 之间的双向绑定这一种。

    然而 React 从诞生之初就不支持双向绑定,React 一直提倡的是单向数据流,他称之为 onChange/setState() 模式。

    不过由于我们一般都会用 Vuex 以及 Redux 等单向数据流的状态管理框架,因此很多时候我们感受不到这一点的区别了。

    HoC 和 mixins

    在 Vue 中我们组合不同功能的方式是通过 mixin,而在 React 中我们通过 HoC (高阶组件)。

    React 最早也是使用 mixins 的,不过后来他们觉得这种方式对组件侵入太强会导致很多问题,就弃用了 mixinx 转而使用 HoC,关于 mixin 究竟哪里不好,可以参见这篇文章 Mixins Considered Harmful。

    而 Vue 一直是使用 mixin 来实现的。

    为什么 Vue 不采用 HoC 的方式来实现呢?

    高阶组件本质就是高阶函数,React 的组件是一个纯粹的函数,所以高阶函数对 React 来说非常简单。

    但是 Vue 就不行了,Vue 中组件是一个被包装的函数,并不简单的就是我们定义组件的时候传入的对象或者函数。比如我们定义的模板怎么被编译的?比如声明的 props 怎么接收到的?这些都是 vue 创建组件实例的时候隐式干的事。由于 vue 默默帮我们做了这么多事,所以我们自己如果直接把组件的声明包装一下,返回一个高阶组件,那么这个被包装的组件就无法正常工作了。

    推荐一篇很棒的文章讲的是 vue 中如何实现高阶组件 探索 Vue 高阶组件

    模板渲染方式的不同

    在表层上, 模板的语法不同

    • React 是通过 JSX 渲染模板
    • 而 Vue 是通过一种拓展的 HTML 语法进行渲染

    但其实这只是表面现象,毕竟 React 并不必须依赖 JSX。 在深层上,模板的原理不同,这才是他们的本质区别:

    • React 是在组件 JS 代码中,通过原生 JS 实现模板中的常见语法,比如插值,条件,循环等,都是通过 JS 语法实现的
    • Vue 是在和组件 JS 代码分离的单独的模板中,通过指令来实现的,比如条件语句就需要 v-if 来实现

    对这一点,我个人比较喜欢 React 的做法,因为他更加纯粹更加原生,而 Vue 的做法显得有些独特,会把 HTML 弄得很乱。举个例子,说明 React 的好处:

    react 中 render 函数是支持闭包特性的,所以我们 import 的组件在 render 中可以直接调用。但是在 Vue 中,由于模板中使用的数据都必须挂在 this 上进行一次中转,所以我们import 一个组件完了之后,还需要在 components 中再声明下,这样显然是很奇怪但又不得不这样的做法。

    Vuex 和 Redux 的区别

    store 注入和使用方式有一些区别。

    在 Vuex 中,$store 被直接注入到了组件实例中,因此可以比较灵活的使用:

    • 使用 dispatchcommit 提交更新
    • 通过 mapState 或者直接通过 this.$store 来读取数据

    在 Redux 中,我们每一个组件都需要显示的用 connect 把需要的 propsdispatch 连接起来。

    另外 Vuex 更加灵活一些,组件中既可以 dispatch action 也可以 commit updates,而 Redux 中只能进行 dispatch,并不能直接调用 reducer 进行修改。

    第 1 条附言    2018-07-26 10:44:43 +08:00
    本人是 Vue 粉,并不精通 React,所以可能有些观点不够精辟。我关于 Vue 的一些心得可以参见这里:
    - [Vue1.0 源码解析系列]( https://github.com/lihongxun945/myblog/issues?q=is%3Aissue+is%3Aopen+label%3Avue1.0%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90)

    另外 [Vue2.x 源码解析系列]( https://github.com/lihongxun945/myblog/issues?q=is%3Aissue+is%3Aopen+label%3AVue2.x%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%E7%B3%BB%E5%88%97) 正在火热更新,每周两篇文章,有兴趣可以订阅下。在完成之后我会单独发一遍。
    第 2 条附言    2018-07-26 10:55:22 +08:00
    感谢 @shenqi 的回复

    我理解他应该说的是这个意思:

    - 监听数据变化这一部分,我写的太简略了,只有几十个字,不过我觉得已经足够表达意思了
    - Vuex 和 Redux 的区别确实没讲到重点,比如 `immutable` ,我今天会把这部分更新下

    另外我会增加一个 组件通信的部分的比较
    第 3 条附言    2018-07-26 11:24:52 +08:00
    已经更新了部分内容,包括:

    - 更新了 Vuex 和 Redux 的区别部分
    - 增加了一个组件通信的区别

    感谢大家的回复,因为 V2EX 已经无法更新,所以我把内容更新到了这里: https://github.com/lihongxun945/myblog/issues/21
    19 条回复    2018-07-26 23:36:38 +08:00
    shenqi
        1
    shenqi  
       2018-07-26 10:04:28 +08:00
    作为一个 React 粉以及 Vue 黑路过,
    另外,监听数据变化 / Vuex 和 Redux 的区别 这些,你看到了表面的现象而已。
    hlwjia
        2
    hlwjia  
    PRO
       2018-07-26 10:07:11 +08:00
    React 粉 + 1
    dilu
        3
    dilu  
       2018-07-26 10:25:40 +08:00
    你说的都很对,我选 React
    starcraft
        4
    starcraft  
       2018-07-26 10:28:06 +08:00 via iPhone
    node 上依旧不是一个一个数量级啊
    lihongxun945
        5
    lihongxun945  
    OP
       2018-07-26 10:41:05 +08:00
    @shenqi 写的有些简陋,主要是对 React 并没有太深入的理解不敢乱写。后续我有新的想法会更新这个文章,当做一个笔记本来用。如果你有更好的见解,也希望能交流一下。
    chairuosen
        6
    chairuosen  
       2018-07-26 10:49:32 +08:00
    @shenqi 你否定了楼主,然后又不说出自己的理解。
    shenqi
        7
    shenqi  
       2018-07-26 11:05:37 +08:00
    @chairuosen #6 有道理。我来说下我的理解。

    @lihongxun945 #5 我说下那两个点的理解。

    监听数据变化:
    vue 通过 getter / setter,这时候会有提前的设置的问题,不好不坏,需要提前定义好有这个属性,也不好不坏。
    react 中,props 和 state 会触发,props 是自己挂载的,这个时候自己能控制,而 state 的变更,官方指定的是 setState 来直接进行,强行 this.state.xx 来修改,是不会触发重新 render。而且 PureComponent 只做单纯的引用比较,超快。
    所以,监听层面,不存在说哪种好那种性能好坏。

    Vuex 和 Redux:
    没用过 Vuex,不好说。
    Redux,一定要 connect,一方面可以基于 props 传值来理解,只有挂在了的 state 才能当该组件的 props,也算是对性能有好处(鉴于 react 的思想)。
    redux 只能通过 dispatch 修改数据,这样子才能监控更爱。
    另外,可能你的理解是目前学院派的 redux。目前有很多 redux 变种(如 redux-sage ),已经把 action 和 reducer 集合使用,所以直接触发 dispatch 就等于直接 commit 了。
    noe132
        8
    noe132  
       2018-07-26 11:14:07 +08:00 via Android
    其实 react 和 vue 我都很喜欢,不过我更喜欢 vue 是因为 vue 可以模板分开写,而且有 scoped css 支持。

    什么时候 vue 或者 react 可以写单文件的 js 组件,用 jsx 的语法,而且还有 scoped css,我觉得就比较完美了。现在的 css module 用起来总感觉怪怪的,不像在写 css
    zoffy
        9
    zoffy  
       2018-07-26 11:17:59 +08:00
    写得很好
    saran
        10
    saran  
       2018-07-26 11:19:35 +08:00 via Android
    用儿了 vue 后还是觉得的 react 更科学。。。
    noe132
        11
    noe132  
       2018-07-26 11:25:29 +08:00
    其实 react 的 HoC 也是有 mixin 的 namespace 冲突问题。更好的解决办法应该是 render prop
    我觉得 vue 类似的应该是 slot 和 slot-scope
    lihongxun945
        12
    lihongxun945  
    OP
       2018-07-26 11:25:58 +08:00
    @shenqi 感谢你的回复,确实之前写的粗糙,你可以看下我刚刚更新的内容
    dcatfly
        13
    dcatfly  
       2018-07-26 12:24:15 +08:00
    @noe132 可以直接写单独的 css 文件通过 webpack 的 css-loader 实现 scoped 区别不大
    doubleflower
        14
    doubleflower  
       2018-07-26 12:43:30 +08:00
    最近又打算试试 vue,用多了 react 换换口味,而且看了 vuex 感觉会比 redux 那货好用

    前几天看了 vue cli,和去年看了那个直接生成一堆脚本不一样了,炸天了,相当于直接做了个 vue 版 parcel 类打包工具
    undermoodzyx
        15
    undermoodzyx  
       2018-07-26 13:25:51 +08:00 via Android
    为啥没人提 ng ,ts 大法好
    cuzfinal
        16
    cuzfinal  
       2018-07-26 15:03:36 +08:00
    说道 ts,react 对 ts 的支持很好,vue 的就没那么完善了。
    lygmqkl
        17
    lygmqkl  
       2018-07-26 15:15:08 +08:00
    快速实现来说 vue 全家桶 ok 的。
    MinonHeart
        18
    MinonHeart  
       2018-07-26 18:15:13 +08:00 via iPhone
    @undermoodzyx angular 大法好(平时不写
    hjdtl
        19
    hjdtl  
       2018-07-26 23:36:38 +08:00
    用个框架还把自己定位 xx 粉 xx 黑的 累不累
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1025 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 23:33 PVG 07:33 LAX 15:33 JFK 18:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86