-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvirtual-dom.html
More file actions
78 lines (70 loc) · 2.17 KB
/
Copy pathvirtual-dom.html
File metadata and controls
78 lines (70 loc) · 2.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>VirtualDom</title>
</head>
<body>
<script>
function createElement(vnode) {
let tagName = vnode.tagName;
let props = vnode.props || {};
let children = vnode.children || [];
if (typeof tagName !== 'string' || tagName.length === 0) {
return null
}
let el = document.createElement(tagName);
for (let propName in props) {
let propValue = props[propName];
el.setAttribute(propName, propValue);
}
children.forEach(child => {
let childEl = (child instanceof VNode) ? createElement(child) : document.createTextNode(child);
el.appendChild(childEl);
});
return el;
}
function updateChildren(vnode, newVnode) {
let children = vnode.children || [];
let newChildren = newVnode.children || [];
// 遍历现有的children
children.forEach((childVnode, index) => {
let newChildVnode = newChildren[index]
// 两者tag一样
if (childVnode.tag === newChildVnode.tag) {
// 深层次对比,递归
updateChildren(childVnode, newChildVnode)
} else {
// 两者tag不一样
replaceNode(childVnode, newChildVnode)
}
})
}
class VNode {
/**
* @param {String} tagName 标签名
* @param {Object} props 元素的属性对象
* @param {Array} children 子节点
*/
constructor(tagName, props = {}, children = []) {
if (typeof tagName !== 'string' || tagName.length === 0) {
throw new Error('Please input correct tag name');
}
this.tagName = tagName;
this.props = props;
this.children = children;
}
render() {
return createElement(this);
};
}
let ul = new VNode('ul', { id: 'list' }, [
new VNode('li', { class: 'item' }, ['item1']),
new VNode('li', { class: 'item' }, ['item2']),
new VNode('li', { class: 'item' }, ['item3']),
]);
let ulElem = ul.render();
document.body.appendChild(ulElem);
</script>
</body>
</html>