其他分享
首页 > 其他分享> > react和vue系统性总结

react和vue系统性总结

作者:互联网

vue项目中的坑

Reac项目中的坑

es6的坑

react和vue比较

相同之处:

不同之处:(1)react如果状态变化,是从根节点开始重新渲染;vue是确定到某一个节点需要变
化,只是更新这个节点;(2)react是用jsx渲染模板;vue使用的是Template模板渲染,还是Html
模板;

vue:

react

react为什么更适合大型项目

vue的key

https://mp.weixin.qq.com/s/GV1LL-oNDPBsfBqcAdo5bA

看一下vue如何操作dom

先看官方解释:

如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

比如现在有一个数组 [1,2,3,4]变成了[2,1,3,4],那么没有 key 的值会采取一种“就地更新策略”,见下图。它不会移动元素节点的位置,而是直接修改元素本身,这样就节省了一部分性能

而对于有 key 值的元素,它的更新方式如下图所示。可以看到,这里它对 DOM 是移除/添加的操作,这是比较耗性能的。

React中的key 

eact官方文档是这样描述key的:

Keys可以在DOM中的某些元素被增加或删除的时候帮助React识别哪些元素发生了变化。因此你应当给数组中的每一个元素赋予一个确定的标识。

react的diff算法是把key当成唯一id然后比对组件的value来确定是否需要更新的,所以如果没有key,react将不会知道该如何更新组件。

你不传key也能用是因为react检测到子组件没有key后,会默认将数组的索引作为key。

react根据key来决定是销毁重新创建组件还是更新组件,原则是:

  • key相同,组件有所变化,react会只更新组件对应变化的属性。

  • key不同,组件会销毁之前的组件,将整个组件重新渲染。

看下react是如何操作DOM的

如果子组件只是受控组件,使用index作为key,可能表面上不会有什么问题,实际上性能会受很大的影响。例如下面的代码:

// ['张三','李四','王五']=>
<ul>
    <li key="0">张三</li>
    <li key="1">李四</li>
    <li key="2">王五</li>
</ul>
// 数组重排 -> ['王五','张三','李四'] =>
<ul>
    <li key="0">王五</li>
    <li key="1">张三</li>
    <li key="2">李四</li>
</ul>

当元素数据源的顺序发生改变时,对应的:

key为0,1,2的组件都发生了变化,三个子组件都会被重新渲染。(这里的重新渲染不是销毁,因为key还在)

相反,我们使用唯一id作为key:

// ['张三','李四','王五']=>
<ul>
    <li key="000">张三</li>
    <li key="111">李四</li>
    <li key="222">王五</li>
</ul>
// 数组重排 -> ['王五','张三','李四'] =>
<ul>
    <li key="222">王五</li>
    <li key="000">张三</li>
    <li key="111">李四</li>
</ul>

根据上面的更新原则,子组件的值和key均未发生变化,只是顺序发生改变,因此react只是将他们做了移动,并未重新渲染。

 

React生命周期

https://zhuanlan.zhihu.com/p/38030418?utm_source=wechat_session&utm_medium=social&utm_oi=1142240990822797312

 16.3以前的生命周期

更新的生命周期

为甚么这个生命周期现在给变了

答:这个生命周期函数的组合在Fiber(React Fiber是什么)之后就显得不合适了,因为,如果要开启async rendering,在render函数之前的所有函数,都有可能被执行多次。长期以来,原有的生命周期函数总是会诱惑开发者在render之前的生命周期函数做一些动作,现在这些动作还放在这些函数中的话,有可能会被调用多次,这肯定不是你想要的结果。

废弃了哪些?

答:随着getDerivedStateFromProps的推出,同时deprecate了一组生命周期API,包括:

为什么引入getDerivedStateFromProps

答:这个getDerivedStateFromProps是一个静态函数,所以函数体内不能访问this,简单说,就是应该一个纯函数,纯函数是一个好东西啊,输出完全由输入决定。(老实做一个运算就行,别在这里搞什么别的动作。比如ajax)

再啰嗦一下:用一个静态函数getDerivedStateFromProps来取代被deprecate的几个生命周期函数,就是强制开发者在render之前只做无副作用的操作,而且能做的操作局限在根据props和state决定新的state,而已。这是进一步施加约束,防止开发者乱来。

getSnapshotBeforeUpdate这个生命周期是什么?(https://zhuanlan.zhihu.com/p/36062486?utm_source=wechat_session&utm_medium=social&utm_oi=1142240990822797312

答:应用场景(另一个常见的 componentWillUpdate 的用例是在组件更新前,读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理。但在 React 开启异步渲染模式后,render 阶段和 commit 阶段之间并不是无缝衔接的,也就是说在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。 )

getSnapshotBeforeUpdate(prevProps, prevState) 会在组件更新之前获取一个 snapshot,并可以将计算得的值或从 DOM 得到的信息传递到 componentDidUpdate(prevProps, prevState, snapshot) 函数的第三个参数,常常用于 scroll 位置定位等场景。

React的diff算法

计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面。

diff策略

React用 三大策略 将O(n^3)复杂度 转化为 O(n)复杂度

策略一(tree diff): Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计。

策略二(component diff): 拥有相同类的两个组件 生成相似的树形结构, 拥有不同类的两个组件 生成不同的树形结构。

策略三(element diff): 对于同一层级的一组子节点,通过唯一id区分。

将Virtual DOM树转换成actual DOM树的最少操作的过程 称为 调和 。

什么是虚拟DOM?

:用JS对象模拟DOM树
 

用 JavaScript 来表示一个 DOM 节点是很简单的事情,你只需要记录它的节点类型、属性,还有子节点:

element.js

function Element (tagName, props, children) {
  this.tagName = tagName
  this.props = props
  this.children = children
}

module.exports = function (tagName, props, children) {
  return new Element(tagName, props, children)
}

例如上面的 DOM 结构就可以简单的表示:

var el = require('./element')

var ul = el('ul', {id: 'list'}, [
  el('li', {class: 'item'}, ['Item 1']),
  el('li', {class: 'item'}, ['Item 2']),
  el('li', {class: 'item'}, ['Item 3'])
])

现在ul只是一个 JavaScript 对象表示的 DOM 结构,这就是虚拟DOM

Fiber架构是啥

改变了之前react的组件渲染机制,新的架构使原来同步渲染的组件现在可以异步化,可中途中断渲染,执行更高优先级的任务。释放浏览器主线程


画Filber渲染树

 

介绍react高阶组件

 

标签:vue,DOM,渲染,系统性,react,state,key,组件
来源: https://blog.csdn.net/jiaojsun/article/details/100170757