加入收藏 | 设为首页 | 会员中心 | 我要投稿 威海站长网 (https://www.0631zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂

发布时间:2019-02-21 19:17:48 所属栏目:优化 来源:佚名
导读:引言 当下,正面临着近几年来的最严重的互联网寒冬,听得最多的一句话便是:相见于江湖~。缩减HC、裁员不绝于耳,大家都是人心惶惶,年前如此,年后想必肯定又是一场更为惨烈的江湖厮杀。但博主始终相信,寒冬之中,人才更是尤为珍贵。只要有过硬的操作和

渲染差异

  • 遍历patchs, 把需要更改的节点取出来
  • 局部更新dom
  1. // diff算法的实现 
  2. function diff(oldTree, newTree) { 
  3.      // 差异收集 
  4.     let pathchs = {} 
  5.     dfs(oldTree, newTree, 0, pathchs) 
  6.     return pathchs 
  7.  
  8. function dfs(oldNode, newNode, index, pathchs) { 
  9.     let curPathchs = [] 
  10.     if (newNode) { 
  11.         // 当新旧节点的 tagName 和 key 值完全一致时 
  12.         if (oldNode.tagName === newNode.tagName && oldNode.key === newNode.key) { 
  13.               // 继续比对属性差异 
  14.             let props = diffProps(oldNode.props, newNode.props) 
  15.             curPathchs.push({ type: 'changeProps', props }) 
  16.             // 递归进入下一层级的比较 
  17.             diffChildrens(oldNode.children, newNode.children, index, pathchs) 
  18.         } else { 
  19.               // 当 tagName 或者 key 修改了后,表示已经是全新节点,无需再比 
  20.             curPathchs.push({ type: 'replaceNode', node: newNode }) 
  21.         } 
  22.     } 
  23.  
  24.      // 构建出整颗差异树 
  25.     if (curPathchs.length) { 
  26.             if(pathchs[index]){ 
  27.                 pathchs[index] = pathchs[index].concat(curPathchs) 
  28.             } else { 
  29.                 pathchs[index] = curPathchs 
  30.             } 
  31.     } 
  32.  
  33. // 属性对比实现 
  34. function diffProps(oldProps, newProps) { 
  35.     let propsPathchs = [] 
  36.     // 遍历新旧属性列表 
  37.     // 查找删除项 
  38.     // 查找修改项 
  39.     // 查找新增项 
  40.     forin(olaProps, (k, v) => { 
  41.         if (!newProps.hasOwnProperty(k)) { 
  42.             propsPathchs.push({ type: 'remove', prop: k }) 
  43.         } else { 
  44.             if (v !== newProps[k]) { 
  45.                 propsPathchs.push({ type: 'change', prop: k , value: newProps[k] }) 
  46.             } 
  47.         } 
  48.     }) 
  49.     forin(newProps, (k, v) => { 
  50.         if (!oldProps.hasOwnProperty(k)) { 
  51.             propsPathchs.push({ type: 'add', prop: k, value: v }) 
  52.         } 
  53.     }) 
  54.     return propsPathchs 
  55.  
  56. // 对比子级差异 
  57. function diffChildrens(oldChild, newChild, index, pathchs) { 
  58.         // 标记子级的删除/新增/移动 
  59.     let { change, list } = diffList(oldChild, newChild, index, pathchs) 
  60.     if (change.length) { 
  61.         if (pathchs[index]) { 
  62.             pathchs[index] = pathchs[index].concat(change) 
  63.         } else { 
  64.             pathchs[index] = change 
  65.         } 
  66.     } 
  67.  
  68.      // 根据 key 获取原本匹配的节点,进一步递归从头开始对比 
  69.     oldChild.map((item, i) => { 
  70.         let keyIndex = list.indexOf(item.key) 
  71.         if (keyIndex) { 
  72.             let node = newChild[keyIndex] 
  73.             // 进一步递归对比 
  74.             dfs(item, node, index, pathchs) 
  75.         } 
  76.     }) 
  77.  
  78. // 列表对比,主要也是根据 key 值查找匹配项 
  79. // 对比出新旧列表的新增/删除/移动 
  80. function diffList(oldList, newList, index, pathchs) { 
  81.     let change = [] 
  82.     let list = [] 
  83.     const newKeys = getKey(newList) 
  84.     oldList.map(v => { 
  85.         if (newKeys.indexOf(v.key) > -1) { 
  86.             list.push(v.key) 
  87.         } else { 
  88.             list.push(null) 
  89.         } 
  90.     }) 
  91.  
  92.     // 标记删除 
  93.     for (let i = list.length - 1; i>= 0; i--) { 
  94.         if (!list[i]) { 
  95.             list.splice(i, 1) 
  96.             change.push({ type: 'remove', index: i }) 
  97.         } 
  98.     } 
  99.  
  100.     // 标记新增和移动 
  101.     newList.map((item, i) => { 
  102.         const key = item.key 
  103.         const index = list.indexOf(key) 
  104.         if (index === -1 || key == null) { 
  105.             // 新增 
  106.             change.push({ type: 'add', node: item, index: i }) 
  107.             list.splice(i, 0, key) 
  108.         } else { 
  109.             // 移动 
  110.             if (index !== i) { 
  111.                 change.push({ 
  112.                     type: 'move', 
  113.                     form: index, 
  114.                     to: i, 
  115.                 }) 
  116.                 move(list, index, i) 
  117.             } 
  118.         } 
  119.     }) 
  120.  
  121.     return { change, list } 

5. Proxy 相比于 defineProperty 的优势

  • 数组变化也能监听到
  • 不需要深度遍历监听
  1. let data = { a: 1 } 
  2. let reactiveData = new Proxy(data, { 
  3.     get: function(target, name){ 
  4.         // ... 
  5.     }, 
  6.     // ... 
  7. }) 

 

  • mode

    • hash
    • history
  • 跳转

    • this.$router.push()
    • <router-link to=""></router-link>
  • (编辑:威海站长网)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读