从设计思路看待 React 和 Vue 的差异
共同特点
它们都为了解决同一个问题UI = f(state)
,即建立 UI 和逻辑的联系。
1. 基于状态的声明式渲染
框架范式主要有两种:命令式 和 声明式。
早年间大范围流行的 JQuery
就是典型的命令式框架,命令式框架最大的特点是关注过程。
声明式渲染的特点是关注结果,声明出用户想要的结果,无需关心怎么实现,过程交给框架处理。
而Vue
和React
都是声明式渲染。
2. 组件化的层次架构
通过封装组件来构建页面。
3. 渐进式的构建方式
可以按照需求渐进地引入附加功能。例如路由、状态管理、实现 SSR 等。
4. 都生成 Virtual DOM
VDOM
的 3 大优点:
相比原生 DOM,属性更少,体积更小
更强的描述能力
多平台的抽象能力
概念与生态
Vue
的定义:构建用户界面的 JavaScript 框架
React
的定义:构建用户界面的 JavaScript 库
实际上前端框架是应该由构建界面的 JS 库+附加的一整套解决方案构成,从这个标准去考虑,Vue 和 React 都是库,而非框架。
在生态方面,
Vue
官方提供了从声明式渲染
到构建工具
的一整套方案
React
官方主要提供了核心库
,路由
、状态管理
都由第三方提供,整合成一套方案
数据驱动视图更新的方式
Vue:响应式数据
。Vue2 为对象属性劫持
,Vue3 为对象代理
,获取数据的时候收集依赖
,更新数据的时候派发更新
。
可以精准更新,但是收集依赖需要耗费额外的性能。
React:数据不可变
。调用方法通知视图更新,重新渲染时比对数据引用是否变化,来决定是否重渲染。
数据变动会导致组件及所有子组件重新渲染,需要手动做性能优化,导致额外的心智负担。但是没有收集依赖导致的额外开销。
声明方式的差异
React
推荐使用JSX
,Vue
推荐使用模板
JSX
可以最大化利用 JS 原生能力(逻辑判断
、递归
、循环
),并且 jsx 还可以用于给对象赋值和作为函数参数。本质上是JS
的语法糖,对 JS
的能力进行了增强。
模板
需要通过框架提供的特定指令
(v-if
, v-for
)实现逻辑判断和循环,模板
最终也会编译成 render
函数,Vue 在编译过程中有标记元素、静态提升等手段,方便在运行时更快地创建虚拟DOM
和比对。
涉及到AOT
和JIT
的概念
AOT
: Ahead of time
,预编译
JIT
: Just in time
,即时编译
React 只有JIT
,是重运行时的框架,而 Vue 则同时具备了AOT
和JIT
。
顺带一提Svelte
是重编译时框架,它通过AOT
建立了自变量与元素的对应关系,从而在运行时省去了根据自变量计算UI变化
的开销。
更新流程的差异
Vue
是组件级框架,这是因为它的更新是从组件出发的,Vue
为每个组件都建立了 watchEffect
,通过发布订阅的模式,内部的自变量变化会通知组件的 effect 回调。
React
是应用级框架,任何自变量的变化都会开启一次遍历应用的更新流程。
React
遍历应用并不意味着性能会变差,它有 2 个优化手段:
React
内部的优化机制:时间切片
、优先级调度
、Hooks
、Suspense
React
提供给开发者的优化 API:shouldComponentUpdate
、React.memo
、PureComponent
等
顺带一提 Svelte
是元素级框架,这因为它通过AOT
直接建立了自变量与元素的联系。
组件化的开发方式
Vue
的组件更像是一个对象,通过配置的方式填充组件的内容和功能
React
的组件分为函数组件和类组件,其中函数组件主线脉络
清晰,就是将state
映射成UI
,其余的都是副作用,是主线的直线流程,让应用有更清晰的逻辑。
INFO
React 从 v16 开始将文档中的Class Component
全面替换为Hooks
+Functional Component
,这意味着官方认为 hooks 才是未来发展的方向。相比Class Component
,hooks 不需要学习各种生命周期的 API,仅仅需要掌握自变量与因变量
映射UI
和产生副作用
这一脉络。
React
倾向于让组件单一职责,划分容器组件和展示组件。
而Vue
则是让组件完成独立的功能,没有刻意强调组件的单一职责。
具体实践中,React
需要开发者自己注重性能优化,因为props
和state
的改变会触发自身的重新渲染,在没有优化的情况下,使用state
的所有子组件也会重新渲染。
而Vue
的响应式数据
能准确地知道数据变更会触发哪些组件进行更新。