V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lihongxun945
V2EX  ›  前端开发

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

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

    转自我的博客,原文地址: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  
       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   ·   实用小工具   ·   2874 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:38 · PVG 08:38 · LAX 16:38 · JFK 19:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.