Vue 和 React 应该算是现在市面上被使用最多的 UI 库了,这篇文章简单地来总结一些,我个人认为非常重要和宏观的对比,不会牵涉到细节方面。
一:二者的共同点
1: 都使用 Virtual DOM
2: 都提供了响应式和组件化的视图组件
3: 核心集中在 UI 层面,类似于路由,状态管理,数据请求都交给其他库
4: 都是单向数据流
二:二者的不同
1: PureComponent && shouldComponentUpdate
在 React 应用中,当某个组件的状态发生变化时,它会以这个组件为根,重新渲染整组组件子树。如果想要避免这一行为,需要使用 PureComponent 或者实现 shouldComponentUpdate 方法。
但是使用 PureComponent 或者 shouldComponentUpdate 的前提是,需要保证改组件的渲染结果都由 props 所决定。如果此组件不符合这个条件,可能就会得不到你想要的渲染结果。
于此相反的是,是否需要重新渲染子组件,是由 Vue 自己完成的,而不需要开发者特定地写代码去实现,使得开发者可以专注于业务的实现上。
2: 视图表现和逻辑要不要分开
这一点可能大家用眼睛一看就知道,在 Vue 里,我们创建一个组件就是创建一个.vue 文件,然后把这个组件需要的 HTML,JS 逻辑,CSS 都放到这一个文件内,和我们传统的 WEB 保持一致。Vue 的组件也被叫做“视图表现组件”。
而 React 的作者认为对于 UI 来说,视图表现,数据和逻辑天然就是耦合的,所以没必要把它们分开,所以 React 创造了 JSX。任何的 JSX 在编译取值之后都成为 JS 对象,所以 JSX 相当于变成了 JS 里面的一种新的数据类型。它可以像 JS 里面的其他数据类型一样,被赋值给一个 JS 变量,可以作为函数参数,可以作为函数返回值,也可以用在 if 或者 for 等流控制语句。
现在我们看到了表面的现象,但是或许要去问一句,为什么这 2 者在这点上的差别有点大。这跟这 2 个库的设计初衷,或者直接说这 2 个库背后的作者背景有很大关系。
我们都知道 React 是由 Facebook 的人开发的,React 最开始的口号是 ”Rethinking Best Practices”,而他们想要 开发者 去 rethink。他们想要传达的是一种新的 理念。你第一次接触 JSX 的时候,你至少得去看以下这个新概念是什么,它又是基于 ES6 的,所以可能在你写下第一行代码之前,至少得先花点时间学习一下新知识。
“Vue 从一开始的定位就是尽可能的降低前端开发的门槛,让更多的人能够更快地上手开发”。所以尽量地不引入新的概念,让熟悉 web 开发的人能更快速和简单地过渡到使用 Vue 开发。
3: 单向数据绑定和双向数据绑定
在这里首先要说一点,经常有人把 单向数据流 和单向数据绑定 搅和到一起。所以我在知乎上居然见到过这样的问题:
React 是单向数据流的,那能不能实现双向数据绑定呢?
怎么?难道假如 React 是双向数据流,那自然就是双向数据绑定了吗?
接下来我们来理清一下概念:
A: 数据绑定 — 是指在一个组件范围内,数据(model)和视图(view)之间的同步关系。
React 是单向数据绑定 ,在 React 里面,假如我们有一个 input,用户操作 input 改变了 input 的值,state 上面的相应的数据并不会自动改变,需要开发者在 input 的 handler 方法里通过“event.target.value
”获取 input 的值,再通过 setState() 方法来改变。
Vue 提供了双向数据绑定 ,通过指令v-model
来实现,例如:<input v-model="message">
。假如用户操作 input,修改了 input 里面的内容,不需要开发者手动去获取 input 的 value,这里的 message
变量会自动更新。
B: 数据流 —- 是指父组件和子组件之间的数据传递
Vue 和 React 都是单向数据流,数据都是只能从父组件传到子组件,都是通过 props 传递的。
如果子组件想要向父组件传递数据,Vue 和 React 里面都可以通过 callback 函数来完成。当我们在父组件里面拿到了某个子组件传递的数据,想要怎么用就取决了父组件了。
子组件做不到(更不应该)去直接改变父组件的数据。因为对于同一个父组件来说,可能很多个子组件都使用了同一个 prop,假如子组件能改变父组件的其中一个数据,那么这就会影响到其他所有的使用了这个数据的子组件。
所以数据绑定和数据流是两个独立的概念,互相之间不影响,更没有因果关系。