vue与react的异同

相同

  • 使用vdom提高重绘性能
  • 提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件。
  • 将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。

不同

vue react
设计思想 可变数据 数据不可变
编写语法 模板(声明式) jsx(编程式)
数据流 数据双向绑定 单项数据流
数据监听 getter/setter 比较引用
逻辑复用 mixins HOC
构建工具 vue-cli create-react-app
跨平台 react native weex
生命周期 —————初始化(4)——
beforeCreate
created
beforeMount
mounted
—————-运行(2)—-
beforeUpdate
updated
—————-销毁(2)—-
beforeDestory
destroyed
—————初始化(5)———
getDefalutProps
getInitialState
componentWillMount
render
componentDidMount
—————-运行(5)————
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
componentDidUpdate
——————销毁(1)————-
componentDidMount
销毁 beforeDestroy+destroyed componentWillUnmount
状态管理 vuex redux
diff算法 双端比较

vue/react的dom diff过程,二者有什么差异

对比树, 未优化的复杂度是O(n^3), 优化之后是O(n)
删除BC节点, 插入K, 改变AG的位置

  1. ['A', 'B', 'C', 'D', 'E', 'F', 'G']
  2. ['D', 'A', 'G', 'F', 'K', 'E']

vue, snabbdom

首尾两个指针,双向遍历, 加速遍历速度
循环

  1. 寻找相同
    1. 两首对比。向后移动
    2. 两位对比。向前移动
    3. 旧首、新尾对比。移动首部到尾部, 向中间移动
    4. 旧尾、新首对比。移动尾部到首部, 向中间移动
  2. 当前新首是否存在于旧集合
    1. 存在。移动
    2. 不存在。插入
  3. 对比新旧集合长度, 添加、删除
  1. if (sameVnode(oldStartVnode, newStartVnode)) {
  2. patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)
  3. oldStartVnode = oldCh[++oldStartIdx]
  4. newStartVnode = newCh[++newStartIdx]
  5. }
  6. else if (sameVnode(oldEndVnode, newEndVnode)) {
  7. patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx)
  8. oldEndVnode = oldCh[--oldEndIdx]
  9. newEndVnode = newCh[--newEndIdx]
  10. }
  11. else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
  12. patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx)
  13. canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))
  14. oldStartVnode = oldCh[++oldStartIdx]
  15. newEndVnode = newCh[--newEndIdx]
  16. }
  17. else if (sameVnode(oldEndVnode, newStartVnode)) {
  18. patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)
  19. canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)
  20. oldEndVnode = oldCh[--oldEndIdx]
  21. newStartVnode = newCh[++newStartIdx]
  22. }
  23. else {// 没有找到相同的可以复用的节点,则新建节点处理
  24. /* 生成一个key与旧VNode的key对应的哈希表(只有第一次进来undefined的时候会生成,也为后面检测重复的key值做铺垫) 比如childre是这样的 [{xx: xx, key: 'key0'}, {xx: xx, key: 'key1'}, {xx: xx, key: 'key2'}] beginIdx = 0 endIdx = 2 结果生成{key0: 0, key1: 1, key2: 2} */
  25. if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
  26. /*如果newStartVnode新的VNode节点存在key并且这个key在oldVnode中能找到则返回这个节点的idxInOld(即第几个节点,下标)*/
  27. idxInOld = isDef(newStartVnode.key)
  28. ? oldKeyToIdx[newStartVnode.key]
  29. : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)
  30. if (isUndef(idxInOld)) { // New element
  31. /*newStartVnode没有key或者是该key没有在老节点中找到则创建一个新的节点*/
  32. createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
  33. } else {
  34. /*获取同key的老节点*/
  35. vnodeToMove = oldCh[idxInOld]
  36. if (sameVnode(vnodeToMove, newStartVnode)) {
  37. /*如果新VNode与得到的有相同key的节点是同一个VNode则进行patchVnode*/
  38. patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)
  39. //因为已经patchVnode进去了,所以将这个老节点赋值undefined
  40. oldCh[idxInOld] = undefined
  41. /*当有标识位canMove实可以直接插入oldStartVnode对应的真实Dom节点前面*/
  42. canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)
  43. } else {
  44. // same key but different element. treat as new element
  45. /*当新的VNode与找到的同样key的VNode不是sameVNode的时候(比如说tag不一样或者是有不一样type的input标签),创建一个新的节点*/
  46. createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
  47. }
  48. }
  49. newStartVnode = newCh[++newStartIdx]
  50. }

react

同层三种操作:插入、移动、删除
同一层级的同组子节点,添加唯一 key 进行区分
image.pngimage.png

  1. 遍历新集合。 判断元素是否存在于旧集合
    • 不存在, 则插入
    • 存在。判断当前位置和之前的位置
      • 当前位置>旧位置, 移动
  2. 遍历旧集合。判断旧元素是否在于新集合
    1. 找不到, 移除旧元素 ``` function patch(newArr, oldArr) { for(let i=0; i oldIndex) {
      1. // move
      } } else { // append } } for(let i=0; i<oldArr.length; i++) { let cur = oldArr[i]; if (!newArr.includes(cur)) { // remove } } }

patch(new, old) ``` http://hcysun.me/vue-design/zh/renderer-diff.html#%E5%8F%8C%E7%AB%AF%E6%AF%94%E8%BE%83%E7%9A%84%E5%8E%9F%E7%90%86

vue/react开发与jQuery开发有什么区别

React16中使用了 Fiber,但是 Vue 是没有 Fiber 的,为什么呢?

原因是二者的优化思路不一样:

  1. Vue 是基于 template 和 watcher 的组件级更新,把每个更新任务分割得足够小,不需要使用到 Fiber 架构,将任务进行更细粒度的拆分
  2. React 是不管在哪里调用 setState,都是从根节点开始更新的,更新任务还是很大,需要使用到 Fiber 将大任务分割为多个小任务,可以中断和恢复,不阻塞主进程执行高优先级的任务