先写一个简单总结,里面涉及到的内容后面慢慢补充
1. 框架本质不同
Vue本质是MVVM框架——Model-View-ViewModel,由MVC发展过来
React是前端组件框架,由后端组件演化而来。
React为什么不是MVVM
首先,MVVM有一个VM层,是实现数据双向绑定的,即视图变化引起数据发生变化,数据发生变化视图也会发生变化,但React是单向数据绑定,只有属性和状态。react,强调的是属性不可变性,单向数据流。内部的状态内部自己控制。(这也是React与Vue的第二个不同)
2. 数据流不同
Vue通过v-model实现组件与DOM之间数据双向绑定。
React不支持数据双向绑定,提倡的是单向数据流(onChange/setState)
- Vue1.0中可以实现两种双向绑定:父子组件之间,props可以双向绑定;组件与DOM之间可以通过v-model双向绑定。
- Vue2.x中去掉了第一种,也就是父子组件之间不能双向绑定了(但是提供了一个语法糖自动帮你通过事件的方式修改),并且Vue2.x已经不鼓励组件对自己的props进行任何修改了。
双向数据流和单向数据流有什么不同
双向绑定: 视图发生改变数据也会改变,数据发生改变也会影响视图。Vue是通过使用数据劫持以及发布者-订阅者模式来实现的,具体过程可以看这个教程——Vue双向绑定原理,教你一步一步实现双向绑定 - 知乎 (zhihu.com)
双向数据流:父元素传递给子元素的props,子元素也可以进行修改并传递给父元素(Vue2已经不支持了)。子元素通过v-model与视图进行双向绑定
单向数据流:父元素传递给子元素的props是不可被修改的。而数据和视图之间也是单向绑定的,即视图发生变化需要手动通过事件修改数据的值。
双向绑定与响应式原理的不同
数据的响应式原理 和 双向绑定 ,响应式原理指的是数据变化视图也会随之更新,是单向绑定。
① 数据劫持 实现 响应式原理 ===> data -> DOM ===> 单项绑定
② v-model ===> props + emit 语法糖 ===> 双向绑定
在 Vue 中单向数据流是隐式创建的,而双向绑定(v-model)是需要你显式地使用的
3. 监听数据变化的实现原理不同
Vue是通过Object.defineProperty将对象的属性进行劫持,添加getter和setter方法来实现的。
React是通过比较引用方式(diff)进行的,当应用的状态发生变化时,全部组件都会重新渲染,可以使用shouldComponentUpdate生命周期函数进行优化,但Vue中相当于是默认做这步优化的
React监听数据变化
React组件高性能之shouldComponentUpdate的使用 - 知乎 (zhihu.com)
React中无论哪个组件的props或state发生变化时,React会构建新的virtual DOM(虚拟DOM),然后通过diff算法把新旧的virtual DOM进行比较,如果新旧virtual DOM树不等则会重新渲染,否则不重新渲染。
由于DOM操作的非常耗时的,因此要提高组件的性能就应该尽可能地减少组件的重新渲染。如果某个props或state改变了并不影响组件的渲染,那么这个时候是不需要重新渲染组件的。
Pure Component: 如果一个组件只和props和state有关系,给定相同的props和state只会渲染相同的结果,那么这个组件就叫作纯组件。使用纯组件也可以避免多余的渲染。
React中函数组件的性能优化
React.memo
当你想要避免父组件发生变化,但是子组件接收父组件的props没有变化时产生的不必要更新,就要用到React.memo
React.memo是一个高阶组件,用来记忆组件上一次的渲染结果,在props没有变化时复用该结果,避免函数组件不必要的更新。
const MemoChild = React.memo(Child)
useMemo、useCallback
useMemo、useCallback都可以用来解决浅层比较的问题,比如React.memo中传入的props是一个函数或者对象,其对比是一个浅层对比,而React每一次重新渲染都会生成一个新的函数或对象,他们的地址不同,也就导致React.memo认为props的内容发生变化了,就会进行更新。
为了解决这种浅层比较的问题,使用useMemo、useCallback来缓存没有发生变化的值和函数
4. 组件写法差异
React使用 JSX + inline style,即HTML和CSS都写进js中
Vue则是HTML、CSS以及js都写在一个页面里,但都分开写,看起来会比较清楚。Vue也支持JSX写法
5. 渲染过程不同
Vue可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。
React在应用的状态被改变时,全部子组件都会重新渲染。通过shouldComponentUpdate这个生命周期方法可以进行控制。
6. 组件通信不同
Vue中组件通信:
- 父组件通过props向子组件传递数据或回调,子组件通过事件向父组件发送消息。
- provide/inject来实现父组件向子组件注入数据,跨层级通信。
React中组件通信:
- 父组件通过props向子组件传递数据或者回调
- 通过context进行跨层级通信。
React 本身并不支持自定义事件,而Vue中子组件向父组件传递消息有两种方式:事件和回调函数,但Vue更倾向于使用事件。在React中我们都是使用回调函数的,这可能是他们二者最大的区别。