二、背景 1、react:专业 react 诞生于2011年( FaxJS), 2013 年 7 月 3 日 v0.3.0 2016 年 3 月 30 日 v0.14.8 2016 年 4 月 9 日 v15.0.0 2017 年 9 月 27 日 v16.0.0,fiber正式诞生 2019 年 react 16.8发布 正式支持 hooks语法。 2020 年 10 月 22 日
解决问题:
React用来解决什么问题,官方网站上这样说道: We build React to solve one problem:building large applications with data that changes over time. 发端于2013年的个人项目,但如今已然成为世界三大前端框架之一,在中国大陆更是前端首选。(面试官问:为什么你学习用vue?答:因为爱国!)
vue群众基础图 如下图:
react整体上是函数式的思想,组件使用jsx语法,all in js,将html与css全都融入javaScript,jsx语法相对来说更加灵活。 vue的整体思想仍然是拥抱经典的html(结构)+css(表现)+js(行为)的形式,vue鼓励开发者使用template模板,并提供指令供开发者使用如v-if、v-show、v-for等指令,因此在开发vue应用的时候会有一种在写经典web应用(结构、表现、行为分离)的感觉。
一些老生常谈的 数据管理(props、data vs state)、组件写法、生命周期异同这里就不比较了。
1、react与vue在列表加key的问题上最终目的是一致的:更准确、更快地拿到oldVnode中对应的vnode节点,提高性能。但是它们实现的算法却有一定的差异。 React在渲染数组时如果子组件没有提供key,会默认将循环的index作为key来用作第一次渲染。 源码本质上就是暴力比较法:由于单链表fiber无法使用双指针算法,所以无法对算法使用双指针优化。总体上经历两轮遍历,第一轮遍历:处理更新的节点。第二轮遍历:处理剩下的不属于更新的节点。 为了降低算法复杂度,React的diff会预设限制:
只对同级元素进行Diff。如果一个DOM节点在前后两次更新中跨越了层级,那么React不会尝试复用他。 vue在diff性能方面要强于react,当我认真阅读了源码与书籍后,佩服至极, 力扣算法题--最长递增子序列 举个例子吧:以数组[2, 11, 6, 8, 1]为例:最终输出的结果为[0, 2, 3],表示最强增长序列的索引分别是0,2,3;对应的值是2,6,8。换句话说,在这个数组中最长连续增长的值就是数组中的2,6,8三个元素。 那么vue3费了这么大的力气,使用这个方法的目的是什么呢? Vue2在DOM-Diff过程中,优先处理特殊场景的情况,即头头比对,头尾比对,尾头比对等。
而Vue3在DOM-Diff过程中,根据 newIndexToOldIndexMap 新老节点索引列表找到最长稳定序列,通过最长增长子序列的算法比对,找出新旧节点中不需要移动的节点,原地复用,仅对需要移动或已经patch(新增删除节点等操作)节点进行操作,最大限度地提升替换效率,相比于Vue2版本是质的提升!
在react中如果某个组件的状态发生改变,react会把此组件以及此组件的所有后代组件重新渲染,不过重新渲染并不代表会全部丢弃上一次的渲染结果,react还是会通过diff去比较两次的虚拟dom最后patch到真实的dom上。虽然如此,如果组件树过大,diff其实还是会有一部分的开销。react内部通过 fiber优化 diff算法,外部建议开发者使用 shouldComponentUpdate pureComponent 来规避问题。
vue2的响应式是Object.defineProperty实现的,并且重写getter``setter等一系列操作实现观察者模式,一旦数据发生变化,不会像react一样去比较整颗组件树,而是去更新数据状态变化了的组件实例。
React生命周期的命名一直都是非常语义化(小声bb:真是又臭又长又难记)
双方都做出了大规模的改动,虽然源码不同,但设计思想以及代码简易程度来看,确实都在进步。
原先繁琐的 compomentDidUpdate生命周期 =》 useEffect,虽然不完全相同,但在大多数场景中,从开发者层面看待,我们更多是关心props或者state中的数据变化之后,会产生了什么后果(副作用),省去了开发者自己比较前后值的过程。(这应该是react借鉴vue watch) vue3组合式api借鉴了react hooks中的部分思想,不得不说,青出于蓝而胜于蓝,再加上框架自己也做出了很多优化工作,在性能上是react比不上的。
由于初始化时源码内部的响应式机制的缘故,新APIwatchEffect甚至都不需要监听是谁发生了变化就可以触发副作用,因为监听的这个过程,全程都是vue3源码中的 Proxy完成的。 不仅如此 vue3更是推出了更贴近原生js的语法,点赞!!!!!!
其实到这里,vue技术栈的同学一定暗自得意,蹦出一句vue yes! 可惜这么好的库也有存在的问题,vue2响应式Object.defineProperty无法监听数组下标和对象后新增的属性值变化已是老生常谈,vue3采用了 Proxy Api解决这些问题的同时,也带来了新的问题,如reactive只能传对象(react useState简单复杂值都可以),而官方推荐的ref却需要通过 .value才能获取值,这着实让社区炸锅,为此vue团队迫于压力不得不推出 toRefs(感兴趣的同学可以了解一下,之前线下我和艺宝探讨过)。 vue中使用 v-on(简写为:) 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。通常使用v-on接收一个需要调用的方法名称。
访问原生DOM事件,可以将$event显式传入method中
普通元素 addEventListener,组件$on React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:
react16将合成事件挂载到 document上,17版本后为root根元素。
Vue鼓励写近似常规HTML的模板。写起来很接近标准 HTML元素,只是多了一些属性。 React推荐你所有的模板通用JavaScript的语法扩展——JSX书写。
8、其他 当然还有其他的一些比较,诸如vue的插槽(slot)与react的props.children。 生命周期:getDerivedStateFormProps、getSnapshotBeforeUpdate
我的看法:
|
2021-06-04
2019-01-10
2019-02-17
2021-09-12
2021-09-30