react和vue系统性总结
作者:互联网
vue项目中的坑
- 1.数组,对象。不能实时变化,必须使用变异方法
- 2.elementyi scope 样式不能使用 去掉scope就可以了
- 3.v-show 和 v-if正确使用
- 4.普通的watch中只能监听到某不对象的变化才会调用,当想监听对象以及对象中属性的变化都调
- 用函数时,可以使用deep:true
- 5.echarts的id值必须唯一
Reac项目中的坑
- 1.在react中怎么引入css文件呢:这样引入css文件:import './style/nav.css' 需要注意的是:webpack.config.js文件中针对css文件引入的包需要loader必须写全,不能简写
- 2.html元素中添加css样式的时候:两种:一种是class名字填写,但是在jsx中class需要写成className; 二种是在行间写样式style={{}}里面放置样式 ;三种是style={colorstyle}里面放置一个变量
- 3.导入css模块化和引入一个文件二者只能选其一
es6的坑
- 深拷贝注意null不是对象
- 一定要先if判断
- let copyObj = JSON.parse(JSON.stringify(obj));慎用
- Map的foreach不能是箭头函数
react和vue比较
相同之处:
- 组件化
- 用虚拟DOM实现快速渲染
- 轻量级
- 响应式组件
- 服务端渲染
- 集成路由工具,打包工具,状态管理工具的难度低
- 优秀的支持和社区
不同之处:(1)react如果状态变化,是从根节点开始重新渲染;vue是确定到某一个节点需要变
化,只是更新这个节点;(2)react是用jsx渲染模板;vue使用的是Template模板渲染,还是Html
模板;
vue:
- 简单的语法和项目配置
- 更快的渲染速度和更小的体积
- vue是确定到某一个节点需要变
化,只是更新这个节点 - 使用的是Template模板
- 如何处理数据(数据是可变的),当向state添加一个新对象的时候,Vue将遍历其中的所有属性并且转换为getter,setter方法,现在Vue的响应系统开始保持对state的跟踪了,当state中的内容发生变化的时候就会自动重新渲染DOM。令人称道的是,Vue中改变state的状态的操作不仅更加简洁,而且它的重新渲染系统也比React 的更快更有效率。
react
- react如果状态变化,是从根节点开始重新渲染;
- 适用于大型项目(为什么?)
- 如何处理数据(state是不可变):通过比较当前state和前一个state来决定何时在DOM中进行重渲染以及渲染的内容,因此需要不可变(immutable)的state。
- Web端和移动端原生APP通吃
- 更大的生态系统,更多的支持和好用的工具
react为什么更适合大型项目
- 模板容易出现很难注意到的运行时错误,同时也很难去测试,重构和分解。
- Javascript模板可以组织成具有很好的分解性和干(DRY)代码的组件。干代码的可重用性和可测试性更好。
- React的不可变应用状态(state)可能写起来不够简洁,但它在大型应用中意义非凡,因为透明度和可测试性在大型项目中变得至关重要。
vue的key
https://mp.weixin.qq.com/s/GV1LL-oNDPBsfBqcAdo5bA
- 有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
-
key
值,可以进行map映射,直接找到相应的值。没有key
值,则需要遍历才能拿到。相比于遍历,映射的速度会更快。
看一下vue如何操作dom
先看官方解释:
如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
比如现在有一个数组 [1,2,3,4]变成了[2,1,3,4],那么没有
key
的值会采取一种“就地更新策略”,见下图。它不会移动元素节点的位置,而是直接修改元素本身,这样就节省了一部分性能而对于有
key
值的元素,它的更新方式如下图所示。可以看到,这里它对 DOM 是移除/添加的操作,这是比较耗性能的。
React中的key
- 有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
- key在diff算法中的使用
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生命周期
16.3以前的生命周期
更新的生命周期
为甚么这个生命周期现在给变了
答:这个生命周期函数的组合在Fiber(React Fiber是什么)之后就显得不合适了,因为,如果要开启async rendering,在render函数之前的所有函数,都有可能被执行多次。长期以来,原有的生命周期函数总是会诱惑开发者在render之前的生命周期函数做一些动作,现在这些动作还放在这些函数中的话,有可能会被调用多次,这肯定不是你想要的结果。
废弃了哪些?
答:随着getDerivedStateFromProps的推出,同时deprecate了一组生命周期API,包括:
- componentWillReceiveProps
- componentWillMount
- componentWillUpdate
为什么引入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