从设计思路看待 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、SuspenseReact提供给开发者的优化 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的响应式数据能准确地知道数据变更会触发哪些组件进行更新。