1
+ function Compile ( el , vm ) {
2
+ this . vm = vm ;
3
+ this . el = document . querySelector ( el ) || document . body ;
4
+
5
+ if ( this . el ) {
6
+ this . fragment = this . node2Fragment ( this . el ) ; //把节点装进 fragment里面
7
+
8
+ this . init ( ) ; //编译
9
+
10
+ this . el . appendChild ( this . fragment ) ;
11
+ }
12
+ }
13
+ Compile . prototype = {
14
+ node2Fragment : function ( el ) {
15
+ var fragment = document . createDocumentFragment ( ) ;
16
+ var child ;
17
+ while ( child = el . firstChild ) {
18
+ fragment . appendChild ( child ) ;
19
+ }
20
+ return fragment ;
21
+ } ,
22
+ init : function ( ) {
23
+ this . compileCore ( this . fragment ) ;
24
+ } ,
25
+ compileCore : function ( el ) {
26
+ let childNodes = el . childNodes ;
27
+ [ ...childNodes ] . forEach ( node => {
28
+ let text = node . textContent ;
29
+ let reg = / \{ \{ ( .* ) \} \} / ;
30
+
31
+ if ( this . isElementNode ( node ) ) {
32
+ this . compileElement ( node ) ;
33
+ } else if ( this . isTextNode ( node ) && reg . test ( text ) ) {
34
+ this . compileText ( node , RegExp . $1 ) ;
35
+ }
36
+
37
+ if ( node . childNodes && node . childNodes . length ) {
38
+ this . compileCore ( node ) ;
39
+ }
40
+ } ) ;
41
+ } ,
42
+ compileElement : function ( node ) {
43
+ let attrs = node . attributes ;
44
+ [ ...attrs ] . forEach ( attr => {
45
+ let attrName = attr . name ; // type v-model
46
+ if ( this . isDirective ( attrName ) ) {
47
+ let value = attr . value ;
48
+ let name = attrName . substring ( 2 ) ;
49
+ if ( this . isEventDrective ( name ) ) {
50
+ this . eventHandler ( node , this . vm , value , name ) ;
51
+ } else {
52
+ this . bind ( node , this . vm , value , 'model' ) ;
53
+
54
+ node . addEventListener ( 'input' , ( ev ) => {
55
+ let newVal = ev . target . value ;
56
+ this . _setVMVal ( this . vm , value , newVal ) ;
57
+ } , false ) ;
58
+ }
59
+ }
60
+ //事件简写 @click="xxx"
61
+ if ( this . isEventDrective2 ( attrName ) ) {
62
+ this . eventHandler ( node , this . vm , attr . value , attr . name ) ;
63
+ }
64
+ } ) ;
65
+ } ,
66
+ compileText : function ( node , exp ) { //文本 {{text}}
67
+ this . bind ( node , this . vm , exp , 'text' ) ;
68
+ } ,
69
+ eventHandler : function ( node , vm , fnName , eventName ) {
70
+ //eventName on:click @click
71
+ let eventType = eventName . split ( / : | @ / ) [ 1 ] ;
72
+ let fn = vm . methods && vm . methods [ fnName ] ;
73
+
74
+ if ( eventType && fn ) {
75
+ node . addEventListener ( eventType , fn . bind ( vm ) , false ) ;
76
+ }
77
+ } ,
78
+ bind : function ( node , vm , exp , sig ) {
79
+ let updaterFn = this . updater [ sig + 'Updater' ] ;
80
+
81
+ updaterFn && updaterFn ( node , this . _getVMVal ( vm , exp ) ) ;
82
+
83
+ new Watcher ( vm , exp , ( value ) => {
84
+ updaterFn && updaterFn ( node , value ) ;
85
+ } ) ;
86
+ } ,
87
+ _setVMVal : function ( vm , exp , newVal ) {
88
+ vm [ exp ] = newVal ;
89
+ } ,
90
+ _getVMVal : function ( vm , exp ) {
91
+ return vm [ exp ] ;
92
+ } ,
93
+ updater : {
94
+ textUpdater : function ( node , val ) {
95
+ node . textContent = val ;
96
+ } ,
97
+ modelUpdater : function ( node , val ) {
98
+ node . value = val ;
99
+ }
100
+ } ,
101
+ isEventDrective2 : function ( attr ) {
102
+ return attr . indexOf ( '@' ) == 0 ;
103
+ } ,
104
+ isDirective : function ( attr ) {
105
+ return attr . indexOf ( 'v-' ) == 0 ;
106
+ } ,
107
+ isEventDrective : function ( name ) {
108
+ return name . indexOf ( 'on' ) == 0 ;
109
+ } ,
110
+ isElementNode : function ( node ) {
111
+ return node . nodeType == 1 ;
112
+ } ,
113
+ isTextNode : function ( node ) {
114
+ return node . nodeType == 3 ;
115
+ }
116
+ } ;
0 commit comments