-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmyVue.js
157 lines (148 loc) · 3.78 KB
/
myVue.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
class myVue{
constructor(obj={}){
this.$el=obj.el;
this.$data=obj.data;
this._binding={};//用于data中的值监听
this._observe(this.$data);
this._complie(this.$el);
}
/*观察者*/
_observe(_data){
let _this=this;
for(var key in _data){
let value;
if(typeof _data[key]==='object'){
_this._observe(_data[key]) //递归直到不为对象为止
}
_this._binding[key]={ //此处将当前key值存入对象中,用于watcher绑定
_watcherList:[]
}
value=_data[key];
_this._define(_data,key,value);
}
}
/*数据劫持*/
_define(_data,key,value){
let _this=this;
Object.defineProperty(_data,key,{
enumerable: true,
configurable: true,
get(){
return value;
},
set(newValue){
if(newValue!=value){
value=newValue;
if(!Object.is(_this.$data,_data)){//判断是否二重对象
Object.keys(_this.$data).forEach((val)=>{
Object.is(_this.$data[val],_data)&&
_this._binding[`${val}.${key}`]._watcherList.forEach((item)=>{ //有值更新对应更新watcher的update
item.update();
})
})
}else{
_this._binding[key]._watcherList.forEach((item)=>{ //有值更新对应更新watcher的update
item.update();
})
}
}
}
})
}
/*模板解析*/
_complie(root){
let _this=this;
let _node=document.querySelector(root),
_nodeList=_node.children;
for(var ele of _nodeList){
let _modelVal=ele.getAttribute('v-model');
if(_modelVal){
if(ele.nodeName=='INPUT'){
let ide='value';
_this._bind(ele,_this,_modelVal,ide)
ele.addEventListener('input',(e)=>{
let _newVal=e.target.value;
let _objArray=_modelVal.split('.');
if(_objArray.length>1){//此处实现的输入时双向的数据绑定
_object(_this.$data,_objArray,_newVal);
}else{
_this.$data[_modelVal]=_newVal;
}
})
}
}else if(!_this._check(ele.innerHTML)){
ele.innerHTML.replace(/^(\{\{)([a-zA-Z0-9.]+)(\}\})$/ig,(val,$1,$2,$3)=>{
let ide='innerHTML';
_this._bind(ele,_this,$2,ide);
ele.innerHTML=_array($2,_this.$data)||'';
})
}
}
}
/*对当前数据进行监听*/
_bind(ele,vm,newVal,ide){
let _this=this;
if(!_this._binding[newVal]){//此处将当前key值存入对象中,用于watcher绑定
_this._binding[newVal]={
_watcherList:[]
}
}
_this._binding[newVal]._watcherList.push(new Watcher(
ele,
vm,
newVal,
ide
))
}
/*校验{{}}*/
_check(input){
input=input.split('');
return input.reduce((pre,cur)=>{
if(pre<0)return pre;
switch (cur) {
case '{':
++pre;
return pre
case '}':
--pre;
return pre
default:
return pre
}
},0)
}
}
/*监听者函数*/
class Watcher{
constructor(node,vm,value,ide){
this.$el=node;
this.$vm=vm;
this.$value=value;
this.$ide=ide;
}
update(){
let _this=this;
let _valArray=_this.$value.split('.');
if(_valArray.length>1){
_this.$el[_this.$ide]=_array(_this.$value,_this.$vm.$data);
}else{
_this.$el[_this.$ide]=_this.$vm.$data[_this.$value];
}
}
}
/*多重对象取值*/
_array=(str,init)=>{
let _valArray=str.split('.');
return _valArray.reduce((pre,cur)=>{
return pre[cur];
},init)
}
/*多重对象赋值*/
_object=(data,objArray,newVal)=>{
let index=objArray.shift();
if(objArray.length!=0){
_object(data[index],objArray,newVal)
}else{
data[index]=newVal;
}
}