简单实现Vue中的MVVM

Talk is cheap, show me the code.

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
class Compiler {
constructor(el, vm) {
// 判断 el 属性 是不是一个元素 如果不是元素 那就获取他
this.el = this.isElementNode(el) ? el : document.querySeletor(el);

this.vm = vm;

let fragment = this.node2fragment(this.el);

// 把节点中的内容进行替换

// 把内容再次塞到页面中
this.el.appendChild(fragment);
}

// 是不是元素节点
isElementNode(node) {
return node.nodeType === 1;
}

// 编译文本的方法
compileText () {
let attributes = node.attributes;
[...attributes].forEach(attr => {

});
}

// 编译元素的方法
compileElement() {

}
// 编译内存中的 DOM 节点
compile(node) {
let childNodes = node.childNode;
[...childNodes].forEach(child => {
// 如果子节点是元素节点
if (this.isElementNode(child)) {
this.compileElement(child);
} else {
this.compileText(child);
}
});
}

// 把节点移动到内存中
node2fragment(node) {
// 创建一个文档碎片
let fragment = document.createDocumentFragment();
let firstChild;
while (firstChild = node.firstChild) {
// appendChild 具有移动性
fragment.appendChild(firstChild);
}
}
}

class Vue {
constructor(options) {
// this.$el $data $options
this.$el = options.el;
this.$data = options.data;
// 这个根元素 存在编译模板
if (this.$el) {
new Compiler(this.$el, this);
}
}
}