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生命周期

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,包括:

  • 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高阶组件

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值