跳至主要內容

左手粘着Vue右手舞着React

Cap原创大约 6 分钟

作为前端开发工程师,当我们左手拿着 Vue,右手拿着 React,关于它们的种种,其实我们都应该是了然于胸的。

宏观概念

拿到一个前端框架,我们更应该如何去看?肯定不是一头扎进 api 的调用方式,也不是一头扎进源码的海洋。我们应该有对比的看,和你熟悉的一个框架去对比。

众所周知,前端接触最多的是浏览器,浏览器也是面向用户最直接的宿主环境。我们的页面,不管是 SPA,SSR
在浏览器呈现出来的,就是 html/css/js。所以我们以结果触发,首先看,这个框架是如何生成 html/css/js 的?
我们先掌握这个宏观概念,再带着疑问去看细节。

所以,对于 vue 和 react,我们从两点切入:

  1. 数据驱动视图
  2. 组件化

数据驱动是这两个框架的相同点。
组件化也是这两个框架的相同点。
这两点是核心思想,而他们之间的不同,就是在实现这两个核心思想时选择的策略不同。

两个人的目的都是罗马,一人走的是水路,一人走的是陆路

组件化

我们从组件化开始,所谓组件化就是拼凑页面的方式,搭积木。我们要做的就是优雅的拆分和重组

回到 hmtl+js+css 的开发模式,假设我们手上拿着这三个文件,

文件的结构是这样的:



如果我们要实现组件化?怎么样去拆分和组合这个文件呢

  1. 函数组件
  2. SFC

React 选择的是函数组件

我把上中下,看成三个函数, 三个 function,html、js、css 都可以写在这个 function 里面

上function
中function
下function

Vue 选择了 SFC(虽然它也支持 JSX)

我把上中下,看成三个文件,三个文件拼凑成一个文件。html、js、css 都在各自的文件里面

上.vue
中.vue
下.vue

这里两者的设计思想其实已经初现端倪了。

一个是用 function 去组合文件。
一个是用文件(模版)去组合文件。

这也就是 vue 的写法更让人容易接受:用文件拼凑的一定是文件。

  1. JSX
  2. options api

单向数据流是两者实现的默契选择。

组件化我们先告一段落

数据驱动

UI 我们通过组件化开发的方式写好了,接下来考虑怎么去实现页面交互,展示页面数据了。

两者都是通过数据的变化而变更 UI,但是两者实现的差别,正是因为各自组件化实现的不同而导致。

react 基于 function,那么很自然,要更新视图,我重新执行当前 function 去进行局部刷新,很合理。

vue 基于 SFC,那么要做的事情就相对有点多(当然是 vue 去做,不是开发者去做)。首先需要编译.vue 文件,进行数据拦截/代理,收集依赖,数据变更的时候触发更新。

这个实现数据驱动的方式不同是核心差异。后续的不同都是基于这个点去延伸的。

react 并不知道什么时候去刷新,因为它没有数据拦截代理,依赖收集。你要刷新,你就 setState。
(这里可以拓展 shouldComponentUpdate)

vue 不同啊,因为它基于模版,它啥都知道啊。所以性能方面,它有的放矢,相比之下有点优势。

正是因为手中有模版,Vue 能在编译阶段做点事情,什么静态提升,类型标记。
这里可以拓展(react 的 fiber)

有了以上这些宏观的概念,我们再跳出来看细节,是不是看到的东西就不一样了。

vue 的 value

vue3 中,这大概是被吐槽最多的地方,拿一个值,需要 count.value 这种方式。
因为 vue 为了实现数据拦截/代理,但是 js 中基本类型是无法通过 Proxy 去代理的。所以妥协策略就是自己再包装一层。

React 的 Class 组件和函数组件

基于 function 的思想去理解 class 组件,那么就能理解基于 class 的能力,它是如何去保存状态,去实现数据流,去构造高阶组件等。

同样也不难理解,基于 function 的逻辑复用解决方案(作用域和参数)

Mixin -> Hoc-> render prop

hooks 的出现,可以简单理解为在函数层面,怎么去规避或解决 class 组件写法带来的问题。函数层面的状态缓存,在 js 中想到的是啥?那当然是闭包,hooks 确实也是利用了闭包来实现的。

个人理解主要有两点:
一:hooks 基于函数式的复用,不会和原来的 class 复用一样,有一堆的 wrapper,也不会改变组件层级,因为它仅仅是函数调用函数
二:淡化生命周期的概念,既然是函数,那就一定有执行顺序。hooks 利用链表来实现每个组件 hooks 的顺序调用(这也就是为什么 hook 要在顶层,不能在一些条件语句中)

以上,你也就不难理解什么叫自定义 hooks:想要复用一个东西,那我在要用的地方都调用同一个函数,这样就 OK 了。

结语

正所谓万变不离其宗。

当我们看到 Vue 的新特性或者 React 的新能力的时候,我们不应该只感慨:好家伙,又要学。

其实我们更应该从本质看现象:哦?这个功能是为了优化什么呢,是为了降低什么心智负担呢?

因为我们心里有两个抓手(函数是一等公民)和(模版与代理)