diff算法实现

大致流程

var vnode = {
  tag: 'ul',
  attrs: {
    id: 'list'
  },
  children: [{
    tag: 'li',
    attrs: {
      className: 'item'
    },
    children: ['item 1']
  },{
    tag: 'li',
    attrs: {
      className: 'item'
    },
    children: ['item 2']
  }]
}
function createElementvnode){
  var tag = vnode.tag;
  var attrs = vnode.attrs || {};
  var children = vnode.children || [];
  if tag == null) {
    return null;
  }

  // 创建真实的 dom 元素
  var elem = document.createElementtag);
  // 属性
  var attrName;
  for attrName in attrs) {
    ifattrs.hasOwnPropertyattrName)){
      elem.setAttributeattrName, attrs[attrName]);
    }
  }
  // 子元素
  children.forEachfunctionchildVnode){
    elem.appendChildchildElemchildVnode)) // 递归
  });

  // 返回真实的 dom 元素
  return elem;
}

就是将对象一一转化成dom

上面是patch的第一个参数没有内容的时候,如果有内容就会做对比。

var vnode = {
  tag: 'ul',
  attrs: {
    id: 'list'
  },
  children: [{
    tag: 'li',
    attrs: {
      className: 'item'
    },
    children: ['item 1']
  },{
    tag: 'li',
    attrs: {
      className: 'item'
    },
    children: ['item 2']
  }]
}

var newVnode = {
  tag: 'ul',
  attrs: {
    id: 'list'
  },
  children: [{
    tag: 'li',
    attrs: {
      className: 'item'
    },
    children: ['item 1']
  },{
    tag: 'li',
    attrs: {
      className: 'item'
    },
  children: ['item b']
  }]
}


function updateChildrenvnode ,newVnode){
  var children = vnode.children || [];
  var newChildren = newVnode.children || [];

  children.forEachfunctionchildrenVnode, index){
    var newChildrenVnode = newChildren[index];
    ifchildrenVnode.tag === newChildrenVnode.tag){
      // 深层次对比,递归
      updateChildrenchildrenVnode, newChildrenVnode);
    } else {
      // 替换
      replaceNodechildrenVnode, newChildrenVnode);
    }
  });
}

function replaceNodevnode, newVnode){
  var elem = vnode.elem; // 真实的 dom
  var newElem = newVnode.elem;

  // 替换
}

没法知道有多少层,就必须用递归

Published by

风君子

独自遨游何稽首 揭天掀地慰生平