-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo.js
174 lines (153 loc) · 5.12 KB
/
demo.js
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// 定义一个myVue构造函数 充当Vue的实例对象
function myVue(opt) {
console.log(this);
// 给一个初始化构造函数的方法
this._init(opt);
}
// 在原型上增加init方法
myVue.prototype._init = function (opt) {
this.$option = opt;
this.$el = document.querySelector(opt.el);
this.$data = opt.data;
this.$methods = opt.methods;
this._binding = {};
this._obverse(this.$data);
this._complie(this.$el);
}
// 建立_obverse 处理data
myVue.prototype._obverse = function (obj) {
var _this = this;
Object.keys(obj).forEach(function (key) {
if (obj.hasOwnProperty(key)) {
_this._binding[key] = {
_directives: []
};
console.log(_this._binding[key])
var value = obj[key];
if (typeof value === 'object') {
_this._obverse(value);
}
var binding = _this._binding[key];
Object.defineProperty(_this.$data, key, {
enumerable: true,
configurable: true,
get: function () {
console.log(`${key}获取${value}`);
return value;
},
set: function (newVal) {
console.log(`${key}更新${newVal}`);
if (value !== newVal) {
value = newVal;
binding._directives.forEach(function (item) {
item.update();
})
}
}
})
}
})
}
// myVue.prototype._obverse = function (obj) {
// var _this = this;
// var value;
// for (var key in obj) {
// if (obj.hasOwnProperty(key)) {
// this._binding[key] = {
// _directives: []
// };
// var binding = this._binding[key];
// value = obj[key];
// if (typeof value === "object") {
// this._obverse(value);
// }
// Object.defineProperty(this.$data, key, {
// enumerable: true,
// configurable: true,
// getter: function () {
// console.log(`获取${value}`);
// },
// setter: function (newVal) {
// console.log(`更新${newVal}`);
// if (value !== newVal) {
// value = newVal;
// binding._directives.forEach((item) => {
// item.update();
// });
// }
// }
// })
// }
// }
// }
myVue.prototype._complie = function (root) { // root 为id为app的Element元素,也就是我们的根元素
var _this = this;
console.log(root);
var nodes = root.children;
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (node.children.length) {
this._complie(node);
}
if (node.hasAttribute('v-click')) {
node.onclick = (function () {
var attrVal = nodes[i].getAttribute('v-click');
return _this.$methods[attrVal].bind(_this.$data);
})();
}
if (node.hasAttribute('v-model') && (node.tagName = 'INPUT' || node.tagName == 'TEXTAREA')) {
node.addEventListener('input', (function (key) {
var attrVal = node.getAttribute('v-model');
_this._binding[attrVal]._directives.push(new Watcher(
'input',
node,
_this,
attrVal,
'value'
))
return function () {
_this.$data[attrVal] = nodes[key].value;
}
})(i));
}
if (node.hasAttribute('v-bind')) {
var attrVal = node.getAttribute('v-bind');
_this._binding[attrVal]._directives.push(new Watcher(
'text',
node,
_this,
attrVal,
'innerHTML'
))
}
}
}
// 建立一个指令类 用来绑定更新函数
function Watcher(name, el, vm, exp, attr) {
this.name = name; //指令名称,例如文本节点,该值设为"text"
this.el = el; //指令对应的DOM元素
this.vm = vm; //指令所属myVue实例
this.exp = exp; //指令对应的值,本例如"number"
this.attr = attr; //绑定的属性值,本例为"innerHTML"
this.update()
}
Watcher.prototype.update = function () {
this.el[this.attr] = this.vm.$data[this.exp]; //比如 H3.innerHTML = this.data.number; 当number改变时,会触发这个update函数,保证对应的DOM内容进行了更新。
}
window.onload = function () {
var app = new myVue({
el: "#app",
data: {
number: 0,
count: 0,
},
methods: {
increment: function () {
this.number++;
},
incre: function () {
this.count++;
}
}
});
}