vdom(2.5)
到這裡應該就是 vdom 的雛形了,沒有使用任何有用的 Diff 演算法
<button id="update">update</button> <div id="root"></div>
let vdom1 = { tag: div, props: { style: border: solid 2px red; }, children: [{ tag: a, props: { id: 1, href: http://test.com, target: _blank }, children: [{ text: click! }] }, { text: text!! }, { tag: div, props: { class: class1 class2, data-attr: hello }, children: [{ text: hahaha! }, { tag: br }] }, { tag: br }] }
let vdom2 = { tag: div, props: { class: vdom2 }, children: [{ tag: a, props: { id: 1, href: http://test.com, target: _blank }, children: [{ text: click!!! }] }, { tag: h2, children: [{ text: hahahah! }] }, { tag: div, props: { class: class1 class2, data-attr: hello }, children: [{ text: xxixii! }, { tag: br }] }, { tag: br }] }
let prev function render(container, root) { function dfs(node, prev = {}) { let element if (node.tag) { if (prev && prev.tag === node.tag) { element = prev.raw updateProps(element, node.props, prev.props) } else { element = createElement(node.tag, node.props) } node.children && renderChildren(node.children, prev.children, element) } else if (typeof node.text === string) { element = createTextNode(node.text) } node.raw = element return node } function renderChildren(children = [], prevChildren = [], parentElement) { children.forEach((child, index) => { let prevChild = null if (prevChildren) prevChild = prevChildren[index] if (prevChild) { let newNode = dfs(child, prevChild) if (prevChild.tag !== child.tag) { parentElement.replaceChild(newNode.raw, prevChild.raw) } } else { let newNode = dfs(child) parentElement.appendChild(newNode.raw) } }) prevChildren.slice(children.length).forEach((child) => { parentElement.removeChild(child.raw) }) } dfs(root, prev) if (!prev) { prev = root container.appendChild(prev.raw) } } function createElement(tag, props = {}) { const element = document.createElement(tag) updateProps(element, props) return element } function updateProps(element, props = {}, oldProps = {}) { Object.keys(oldProps).forEach((key) => { element.removeAttribute(key) }) Object.keys(props).forEach((key) => { element.setAttribute(key, props[key]) }) } function createTextNode(text) { return document.createTextNode(text) } let fake1 = render(root, vdom1) update.addEventListener(click, () => { fake2 = render(root, vdom2) })
推薦閱讀:
※Python基礎_1.數據結構與演算法_簡單數據結構
※數據結構: B-Tree 簡介及插入
※劍指Offer Python實現
※數據結構與演算法:堆排序
※QG之魔鬼訓練營系列:第二周周記