谈谈vue和react
vue和react之间的区别理解,涉及好几个方面,如下
社区生态
- React 官方只关注底层,上层应用解决方案都交给社区,所以 React 生态体系丰富,社区强,比如这个状态管理,React社区生态上就出现好多,比如这个redux、mobx、dva、zustand等等,而 Vue官方提供了路由和状态管理的解决方案。
底层: 是框架的具体实现
上层应用:在底层的基础上去构建应用程序的层面上的开发和解决方案
api方面
- vue相比react 提供了很多api, 比如自定义指令、插槽、定义数据的方式 【ref、reactive,而这2个的用法,在社区中也是出现很多写法】等等, react的api比较少,可以更自由灵活
hooks方面
- React hook 是根据链表的索引顺序来读取hooks状态,来确定下一次重新渲染时的状态来源,所以有一些限制,比如不能在循环/条件判断/嵌套函数里使用,而且必须在函数最顶层调用 hook
- Vue3 hook 也就是 Composition 组合式 API 是基于响应式实现的,它是声明在 setup 里,一次组件实例化只调用一次 setup,而 React 每次重新渲染都要重新调用,vue的composition可以在循环/条件判断/嵌套函数里使用,所以vue在使用hooks可以更灵活, 正因为是基于响应式实现的,还自动实现了依赖收集,而 React 需要手动传入依赖
对数据的反应不同:
- vue是响应式的,是MVVM模式,有双向数据绑定,vue当数据改动时,界面就会自动更新
- react如果需要视图更新,要手动调用方法setState
模板的语法不同
模板的语法不同,React是通过JSX渲染模板,Vue 是通过 template 模版进行编译的
- Vue是提倡使用 template模板的,可以在编译的时候可以很好对静态节点进行分析
- 而react是没有静态分析的,JSX本质是js语言,是动态的,很难做静态分析
diff 算法的不同点:
-
Vue diff使用双向链表, 从两头向中间进行遍历
-
React diff使用了单向链表,从左到右进行遍历
-
对静态节点的处理不一样。
- 由于 Vue 是通过 template 模版进行编译的,所以在编译的时候可以很好对静态节点进行分析然后进行打补丁标记,然后在 Diff 的时候,Vue2 是判断如果是静态节点则跳过过循环对比,而 Vue3 则是把整个静态节点进行提升处理,Diff 的时候是不过进入循环的,所以 Vue3 比 Vue2 的 Diff 性能更高效
- React 因为是通过 JSX 进行编译的,是无法进行静态节点分析的
Vue 是不提倡使用 JSX的,使用也没有问题,Vue 使用了 JSX 就没办法静态编译优化了
JSX本质是js语音,是动态的,很难做静态分析,所以无法做编译时优化,react的性能优化集中在运行时进行处理
vue template是静态的声明,可以在编译阶段优化
监听数据变化的实现原理不同 【响应数据变化实现不同】
响应式:状态更新,UI自动更新。
-
Vue 使用数据劫持和观察者模式来监听数据变化,当数据发生变化时,Vue 会通知订阅者进行重新渲染。这种方式可以保证页面的性能。
- Vue3使用了Proxy对象来替代Vue2中的Object.defineProperty()方法,Proxy对象可以对整个对象进行劫持
-
React的数据变化监听是基于虚拟DOM(Virtual DOM)的。当组件的状态或者 props 发生变化时,React会先在内存中创建一个新的虚拟DOM树,然后将新的虚拟DOM树与旧的虚拟DOM树进行比较,找出发生变化的部分,并更新到真实的DOM上,这样就实现了组件的更新
-
React 默认是通过比较引用来判断数据变化的
-
当组件的状态或者 props 发生变化时,React 会比对新旧状态或者 props 的引用是否相同
-
依赖收集不同
- react useEffect/useMemo需要手动加依赖,但vue3的运行时会自动收集wachEffect和computed依赖,不用手动声明依赖
- vue3可以更智能的依赖收集
所以react的门槛会高一点,需要开发者手动指定依赖,会对前端开发的专业性比较高,需要有一定的基础
闭包陷阱问题
- vue不需要担心闭包陷阱的问题
- vue的
script setup仅执行一遍,而React 函数式组件 每次渲染都会执行 (容易会导致闭包陷阱)
- vue的
- vue 状态改变,也不会触发 setup 的更新,保证只有一个引用关系
react需要fiber和时间分片而vue没有
vue不需要时间切片原因:
- 时间切片只能对大量的CPU计算进行优化,无法优化复杂的DOM操作,因为要确保用户正在操作的界面是最新的状态才可以
- 而由于React里会经常出现CPU计算量大的场景 【100毫秒以上的计算量】
- React由于使用JSX导致它的渲染效率比 template 低,因为 template 很容易做静态分析和优化
- jsx是比较动态的,需要做静态分析是很难的
- React的应用需要开发者手动优化,默认会有render渲染过多的问题,比如需要加useMemo优化渲染效率,指定正确的依赖数组,指定依赖这个在react中很难做到自动化
- React由于使用JSX导致它的渲染效率比 template 低,因为 template 很容易做静态分析和优化
- 对比之下,vue解决了上述的问题,vue的template模板优化 【静态分析、静态提升】,而且vue通过数据响应式追踪,Vue 可以做到组件树级别的优化,比如把插槽编译为函数以避免 children 的变化引发 re-render,比如自动缓存内联事件处理函数以避免 re-render。Vue 3 可以做到在不借助开发者的任何手动优化的情况下,防止子组件在非必要的情况下 re-render。这意味着同样一次更新,React 应用可能要 re-render 多个组件,而 Vue 应用很可能只 re-render 一个组件
- 在默认情况下,Vue3 应用会比 React 应用少花费很多CPU 时间,所以vue不需要时间切片,也就不需要fiber
vue和react更新机制
react更新机制
- 1、将虚拟DOM转换Fiber树
- 2、通过reconcile调度处理,来管理任务优先级和执行顺序
vue更新机制
- 1、vue通过响应式方式来进行收集依赖和依赖更新
- 2、当数据发生变化时,会通知相关依赖进行更新,从而更新视图
vue和react都组件更新机制
- React 中,父组件 state 更新后,普通子组件默认会重新 render;即使 diff 后 DOM 没变,组件函数执行和 diff 本身也有成本,所以大列表可能卡顿。要避免需要
React.memo、稳定 props、状态下沉等。 - Vue 中,父组件响应式状态更新后,父组件会重新 render,子组件 vnode 会被重新生成并进入 patch 检查;但如果子组件的 props、slots、attrs 等没有变化,Vue 通常不会重新执行子组件 render。所以 Vue 在这类场景下默认比 React 更细粒度一些
- vue这里 props、slots、attrs 会进行类似浅比较,基本类型直接比值,对于对象通过引用地址是否一致