@@ -66,9 +66,16 @@ export const walk = (node: Node, ctx: Context): ChildNode | null | void => {
66
66
67
67
// v-scope
68
68
if ( ( exp = checkAttr ( el , 'v-scope' ) ) || exp === '' ) {
69
- ctx = createScopedContext ( ctx , exp ? evaluate ( ctx . scope , exp ) : { } )
69
+ const scope = exp ? evaluate ( ctx . scope , exp ) : { }
70
+ ctx = createScopedContext ( ctx , scope )
71
+ if ( scope . $template ) {
72
+ resolveTemplate ( el , scope . $template )
73
+ }
70
74
}
71
75
76
+ // process children first before self attrs
77
+ walkChildren ( el , ctx )
78
+
72
79
// other directives
73
80
let deferredModel
74
81
for ( const { name, value } of [ ...el . attributes ] ) {
@@ -98,19 +105,20 @@ export const walk = (node: Node, ctx: Context): ChildNode | null | void => {
98
105
segments . push ( `$s(${ match [ 1 ] } )` )
99
106
lastIndex = match . index + match [ 0 ] . length
100
107
}
101
- if ( lastIndex < data . length - 1 ) {
108
+ if ( lastIndex < data . length ) {
102
109
segments . push ( JSON . stringify ( data . slice ( lastIndex ) ) )
103
110
}
104
111
applyDirective ( node , text , segments . join ( '+' ) , ctx )
105
112
}
113
+ } else if ( type === 11 ) {
114
+ walkChildren ( node as DocumentFragment , ctx )
106
115
}
116
+ }
107
117
108
- if ( type === 1 || type === 11 ) {
109
- // element or fragment - process children
110
- let child = node . firstChild
111
- while ( child ) {
112
- child = walk ( child , ctx ) || child . nextSibling
113
- }
118
+ const walkChildren = ( node : Element | DocumentFragment , ctx : Context ) => {
119
+ let child = node . firstChild
120
+ while ( child ) {
121
+ child = walk ( child , ctx ) || child . nextSibling
114
122
}
115
123
}
116
124
@@ -165,3 +173,17 @@ const applyDirective = (
165
173
ctx . cleanups . push ( cleanup )
166
174
}
167
175
}
176
+
177
+ const resolveTemplate = ( el : Element , template : string ) => {
178
+ if ( template [ 0 ] === '#' ) {
179
+ const templateEl = document . querySelector ( template )
180
+ if ( import . meta. env . DEV && ! templateEl ) {
181
+ console . error (
182
+ `template selector ${ template } has no matching <template> element.`
183
+ )
184
+ }
185
+ el . appendChild ( ( templateEl as HTMLTemplateElement ) . content . cloneNode ( true ) )
186
+ return
187
+ }
188
+ el . innerHTML = template
189
+ }
0 commit comments