@@ -97,6 +97,40 @@ export function parse (
97
97
}
98
98
99
99
function closeElement ( element ) {
100
+ if ( ! inVPre && ! element . processed ) {
101
+ element = processElement ( element , options , currentParent )
102
+ }
103
+ // tree management
104
+ if ( ! stack . length && element !== root ) {
105
+ // allow root elements with v-if, v-else-if and v-else
106
+ if ( root . if && ( element . elseif || element . else ) ) {
107
+ if ( process . env . NODE_ENV !== 'production' ) {
108
+ checkRootConstraints ( element )
109
+ }
110
+ addIfCondition ( root , {
111
+ exp : element . elseif ,
112
+ block : element
113
+ } )
114
+ } else if ( process . env . NODE_ENV !== 'production' ) {
115
+ warnOnce (
116
+ `Component template should contain exactly one root element. ` +
117
+ `If you are using v-if on multiple elements, ` +
118
+ `use v-else-if to chain them instead.` ,
119
+ { start : element . start }
120
+ )
121
+ }
122
+ }
123
+ if ( currentParent && ! element . forbidden ) {
124
+ if ( element . elseif || element . else ) {
125
+ processIfConditions ( element , currentParent )
126
+ } else if ( element . slotScope ) { // scoped slot
127
+ const name = element . slotTarget || '"default"'
128
+ ; ( currentParent . scopedSlots || ( currentParent . scopedSlots = { } ) ) [ name ] = element
129
+ } else {
130
+ currentParent . children . push ( element )
131
+ element . parent = currentParent
132
+ }
133
+ }
100
134
// check pre state
101
135
if ( element . pre ) {
102
136
inVPre = false
@@ -110,6 +144,23 @@ export function parse (
110
144
}
111
145
}
112
146
147
+ function checkRootConstraints ( el ) {
148
+ if ( el . tag === 'slot' || el . tag === 'template' ) {
149
+ warnOnce (
150
+ `Cannot use <${ el . tag } > as component root element because it may ` +
151
+ 'contain multiple nodes.' ,
152
+ { start : el . start }
153
+ )
154
+ }
155
+ if ( el . attrsMap . hasOwnProperty ( 'v-for' ) ) {
156
+ warnOnce (
157
+ 'Cannot use v-for on stateful component root element because ' +
158
+ 'it renders multiple elements.' ,
159
+ el . rawAttrsMap [ 'v-for' ]
160
+ )
161
+ }
162
+ }
163
+
113
164
parseHTML ( template , {
114
165
warn,
115
166
expectHTML : options . expectHTML ,
@@ -174,62 +225,15 @@ export function parse (
174
225
processFor ( element )
175
226
processIf ( element )
176
227
processOnce ( element )
177
- // element-scope stuff
178
- processElement ( element , options )
179
228
}
180
229
181
- function checkRootConstraints ( el ) {
182
- if ( process . env . NODE_ENV !== 'production' ) {
183
- if ( el . tag === 'slot' || el . tag === 'template' ) {
184
- warnOnce (
185
- `Cannot use <${ el . tag } > as component root element because it may ` +
186
- 'contain multiple nodes.' ,
187
- { start : el . start }
188
- )
189
- }
190
- if ( el . attrsMap . hasOwnProperty ( 'v-for' ) ) {
191
- warnOnce (
192
- 'Cannot use v-for on stateful component root element because ' +
193
- 'it renders multiple elements.' ,
194
- el . rawAttrsMap [ 'v-for' ]
195
- )
196
- }
197
- }
198
- }
199
-
200
- // tree management
201
230
if ( ! root ) {
202
231
root = element
203
- checkRootConstraints ( root )
204
- } else if ( ! stack . length ) {
205
- // allow root elements with v-if, v-else-if and v-else
206
- if ( root . if && ( element . elseif || element . else ) ) {
207
- checkRootConstraints ( element )
208
- addIfCondition ( root , {
209
- exp : element . elseif ,
210
- block : element
211
- } )
212
- } else if ( process . env . NODE_ENV !== 'production' ) {
213
- warnOnce (
214
- `Component template should contain exactly one root element. ` +
215
- `If you are using v-if on multiple elements, ` +
216
- `use v-else-if to chain them instead.` ,
217
- { start : element . start }
218
- )
219
- }
220
- }
221
- if ( currentParent && ! element . forbidden ) {
222
- if ( element . elseif || element . else ) {
223
- processIfConditions ( element , currentParent )
224
- } else if ( element . slotScope ) { // scoped slot
225
- currentParent . plain = false
226
- const name = element . slotTarget || '"default"'
227
- ; ( currentParent . scopedSlots || ( currentParent . scopedSlots = { } ) ) [ name ] = element
228
- } else {
229
- currentParent . children . push ( element )
230
- element . parent = currentParent
232
+ if ( process . env . NODE_ENV !== 'production' ) {
233
+ checkRootConstraints ( root )
231
234
}
232
235
}
236
+
233
237
if ( ! unary ) {
234
238
currentParent = element
235
239
stack . push ( element )
@@ -370,20 +374,29 @@ function processRawAttrs (el) {
370
374
}
371
375
}
372
376
373
- export function processElement ( element : ASTElement , options : CompilerOptions ) {
377
+ export function processElement (
378
+ element : ASTElement ,
379
+ options : CompilerOptions ,
380
+ parent : ASTElement | undefined
381
+ ) {
374
382
processKey ( element )
375
383
376
384
// determine whether this is a plain element after
377
385
// removing structural attributes
378
- element . plain = ! element . key && ! element . attrsList . length
386
+ element . plain = (
387
+ ! element . key &&
388
+ ! element . scopedSlots &&
389
+ ! element . attrsList . length
390
+ )
379
391
380
392
processRef ( element )
381
- processSlot ( element )
393
+ processSlot ( element , parent )
382
394
processComponent ( element )
383
395
for ( let i = 0 ; i < transforms . length ; i ++ ) {
384
396
element = transforms [ i ] ( element , options ) || element
385
397
}
386
398
processAttrs ( element )
399
+ return element
387
400
}
388
401
389
402
function processKey ( el ) {
0 commit comments