The general process
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 createElement(vnode){ var tag = vnode.tag; var attrs = vnode.attrs || {}; var children = vnode.children || []; if (tag == null) { return null; } // 创建真实的 dom 元素 var elem = document.createElement(tag); // 属性 var attrName; for (attrName in attrs) { if(attrs.hasOwnProperty(attrName)){ elem.setAttribute(attrName, attrs[attrName]); } } // 子元素 children.forEach(function(childVnode){ elem.appendChild (childElem (childVnode)) // recursive }); // returns true dom element return elem; }
The object is to be converted into eleven dom
The above is the first parameter of the patch without content, if there is content will do comparison.
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 updateChildren(vnode ,newVnode){ var children = vnode.children || []; var newChildren = newVnode.children || []; children.forEach(function(childrenVnode, index) { var newChildrenVnode = newChildren [index]; IF (childrenVnode.tag === newChildrenVnode.tag) { // deep contrast, recursive updateChildren is (childrenVnode, newChildrenVnode); } the else { // Replace replaceNode (childrenVnode , newChildrenVnode); } }); } function replaceNode (the vnode, newVnode) { var elem = vnode.elem; // real DOM var newElem = newVnode.elem; // replace }
No way of knowing how many layers, it is necessary to use recursion