4
4
* @see https://github.com/zzz945/write-vue3-from-scratch/blob/master/doc/zh-cn.md
5
5
*/
6
6
import { VNode } from "./vnode" ;
7
+ import { Watcher } from "./watcher" ;
7
8
8
9
export class Vue3 {
9
10
constructor ( options ) {
10
11
this . $options = options ;
11
12
this . initProps ( ) ;
12
13
this . proxy = this . initDataProxy ( ) ;
14
+ this . initWatcher ( ) ;
13
15
this . initWatch ( ) ;
14
16
15
17
return this . proxy ;
@@ -19,7 +21,7 @@ export class Vue3 {
19
21
* @see https://stackoverflow.com/questions/37714787/can-i-extend-proxy-with-an-es2015-class
20
22
*/
21
23
initDataProxy ( ) {
22
- const data = this . $options . data ? this . $options . data ( ) : { } ;
24
+ const data = this . $data = this . $ options. data ? this . $options . data ( ) : { } ;
23
25
const props = this . $props ;
24
26
const computed = this . $options . computed || { } ;
25
27
@@ -112,11 +114,34 @@ export class Vue3 {
112
114
this . $watch ( key , this . update . bind ( this ) ) ; // 依赖收集
113
115
this . collected [ key ] = true ;
114
116
}
117
+
118
+ if ( this . $target ) {
119
+ this . $watch ( key , this . $target . update . bind ( this . $target ) ) ;
120
+ }
115
121
}
116
122
117
- initWatch ( ) {
123
+ initWatcher ( ) {
118
124
this . dataNotifyChain = { } ;
119
125
}
126
+
127
+ initWatch ( ) {
128
+ const watch = this . $options . watch || { } ;
129
+ const data = this . $data ;
130
+ const computed = this . $options . computed || { } ;
131
+
132
+ for ( let key in watch ) {
133
+ const handler = watch [ key ] ;
134
+
135
+ if ( key in data ) {
136
+ this . $watch ( key , handler . bind ( this . proxy ) ) ;
137
+ } else if ( key in computed ) {
138
+ new Watcher ( this . proxy , computed [ key ] , handler ) ;
139
+ } else {
140
+ throw 'the watching key must be keys of data or computed' ;
141
+ }
142
+ }
143
+
144
+ }
120
145
121
146
notify ( key , prev , current ) {
122
147
( this . dataNotifyChain [ key ] || [ ] ) . forEach ( ( cb ) => cb ( prev , current ) ) ;
@@ -202,13 +227,16 @@ export class Vue3 {
202
227
}
203
228
204
229
update ( ) {
205
- const parent = this . $el . parentElement ;
206
- const vnode = this . $options . render . call ( this . proxy , this . createElement . bind ( this ) ) ;
207
- const oldElement = this . $el ;
208
- this . $el = this . patch ( null , vnode ) ;
230
+ const parent = ( this . $el || { } ) . parentElement ;
209
231
210
- if ( parent ) {
211
- parent . replaceChild ( this . $el , oldElement ) ;
232
+ if ( this . $options . render ) {
233
+ const vnode = this . $options . render . call ( this . proxy , this . createElement . bind ( this ) ) ;
234
+ const oldElement = this . $el ;
235
+ this . $el = this . patch ( null , vnode ) ;
236
+
237
+ if ( parent ) {
238
+ parent . replaceChild ( this . $el , oldElement ) ;
239
+ }
212
240
}
213
241
}
214
242
0 commit comments