大致流程
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; // 替换 }
没法知道有多少层,就必须用递归