@@ -24,7 +24,8 @@ import {
24
24
RESOLVE_COMPONENT ,
25
25
MERGE_PROPS ,
26
26
TO_HANDLERS ,
27
- PORTAL
27
+ PORTAL ,
28
+ SUSPENSE
28
29
} from '../runtimeHelpers'
29
30
import { getInnerRange , isVSlot , toValidAssetId } from '../utils'
30
31
import { buildSlots } from './vSlot'
@@ -36,130 +37,126 @@ const directiveImportMap = new WeakMap<DirectiveNode, symbol>()
36
37
37
38
// generate a JavaScript AST for this element's codegen
38
39
export const transformElement : NodeTransform = ( node , context ) => {
39
- if ( node . type === NodeTypes . ELEMENT ) {
40
- if (
41
- node . tagType === ElementTypes . ELEMENT ||
42
- node . tagType === ElementTypes . COMPONENT ||
43
- node . tagType === ElementTypes . PORTAL ||
44
- // <template> with v-if or v-for are ignored during traversal.
45
- // <template> without v-slot should be treated as a normal element.
46
- ( node . tagType === ElementTypes . TEMPLATE && ! node . props . some ( isVSlot ) )
47
- ) {
48
- // perform the work on exit, after all child expressions have been
49
- // processed and merged.
50
- return ( ) => {
51
- const isComponent = node . tagType === ElementTypes . COMPONENT
52
- const isPortal = node . tagType === ElementTypes . PORTAL
53
- let hasProps = node . props . length > 0
54
- let patchFlag : number = 0
55
- let runtimeDirectives : DirectiveNode [ ] | undefined
56
- let dynamicPropNames : string [ ] | undefined
40
+ if (
41
+ node . type !== NodeTypes . ELEMENT ||
42
+ // handled by transformSlotOutlet
43
+ node . tagType === ElementTypes . SLOT ||
44
+ // <template v-if/v-for> should have already been replaced
45
+ // <templte v-slot> is handled by buildSlots
46
+ ( node . tagType === ElementTypes . TEMPLATE && node . props . some ( isVSlot ) )
47
+ ) {
48
+ return
49
+ }
50
+ // perform the work on exit, after all child expressions have been
51
+ // processed and merged.
52
+ return ( ) => {
53
+ const isComponent = node . tagType === ElementTypes . COMPONENT
54
+ let hasProps = node . props . length > 0
55
+ let patchFlag : number = 0
56
+ let runtimeDirectives : DirectiveNode [ ] | undefined
57
+ let dynamicPropNames : string [ ] | undefined
57
58
58
- if ( isComponent ) {
59
- context . helper ( RESOLVE_COMPONENT )
60
- context . components . add ( node . tag )
61
- }
59
+ if ( isComponent ) {
60
+ context . helper ( RESOLVE_COMPONENT )
61
+ context . components . add ( node . tag )
62
+ }
62
63
63
- const args : CallExpression [ 'arguments' ] = [
64
- isComponent
65
- ? toValidAssetId ( node . tag , `component` )
66
- : isPortal
67
- ? context . helper ( PORTAL )
68
- : `"${ node . tag } "`
69
- ]
70
- // props
71
- if ( hasProps ) {
72
- const propsBuildResult = buildProps ( node , context )
73
- patchFlag = propsBuildResult . patchFlag
74
- dynamicPropNames = propsBuildResult . dynamicPropNames
75
- runtimeDirectives = propsBuildResult . directives
76
- if ( ! propsBuildResult . props ) {
77
- hasProps = false
78
- } else {
79
- args . push ( propsBuildResult . props )
80
- }
64
+ const args : CallExpression [ 'arguments' ] = [
65
+ isComponent
66
+ ? toValidAssetId ( node . tag , `component` )
67
+ : node . tagType === ElementTypes . PORTAL
68
+ ? context . helper ( PORTAL )
69
+ : node . tagType === ElementTypes . SUSPENSE
70
+ ? context . helper ( SUSPENSE )
71
+ : `"${ node . tag } "`
72
+ ]
73
+ // props
74
+ if ( hasProps ) {
75
+ const propsBuildResult = buildProps ( node , context )
76
+ patchFlag = propsBuildResult . patchFlag
77
+ dynamicPropNames = propsBuildResult . dynamicPropNames
78
+ runtimeDirectives = propsBuildResult . directives
79
+ if ( ! propsBuildResult . props ) {
80
+ hasProps = false
81
+ } else {
82
+ args . push ( propsBuildResult . props )
83
+ }
84
+ }
85
+ // children
86
+ const hasChildren = node . children . length > 0
87
+ if ( hasChildren ) {
88
+ if ( ! hasProps ) {
89
+ args . push ( `null` )
90
+ }
91
+ if ( isComponent ) {
92
+ const { slots, hasDynamicSlots } = buildSlots ( node , context )
93
+ args . push ( slots )
94
+ if ( hasDynamicSlots ) {
95
+ patchFlag |= PatchFlags . DYNAMIC_SLOTS
81
96
}
82
- // children
83
- const hasChildren = node . children . length > 0
84
- if ( hasChildren ) {
85
- if ( ! hasProps ) {
86
- args . push ( `null` )
87
- }
88
- if ( isComponent ) {
89
- const { slots, hasDynamicSlots } = buildSlots ( node , context )
90
- args . push ( slots )
91
- if ( hasDynamicSlots ) {
92
- patchFlag |= PatchFlags . DYNAMIC_SLOTS
93
- }
94
- } else if ( node . children . length === 1 ) {
95
- const child = node . children [ 0 ]
96
- const type = child . type
97
- // check for dynamic text children
98
- const hasDynamicTextChild =
99
- type === NodeTypes . INTERPOLATION ||
100
- type === NodeTypes . COMPOUND_EXPRESSION
101
- if ( hasDynamicTextChild && ! isStaticNode ( child ) ) {
102
- patchFlag |= PatchFlags . TEXT
103
- }
104
- // pass directly if the only child is a text node
105
- // (plain / interpolation / expression)
106
- if ( hasDynamicTextChild || type === NodeTypes . TEXT ) {
107
- args . push ( child )
108
- } else {
109
- args . push ( node . children )
110
- }
111
- } else {
112
- args . push ( node . children )
113
- }
97
+ } else if ( node . children . length === 1 ) {
98
+ const child = node . children [ 0 ]
99
+ const type = child . type
100
+ // check for dynamic text children
101
+ const hasDynamicTextChild =
102
+ type === NodeTypes . INTERPOLATION ||
103
+ type === NodeTypes . COMPOUND_EXPRESSION
104
+ if ( hasDynamicTextChild && ! isStaticNode ( child ) ) {
105
+ patchFlag |= PatchFlags . TEXT
114
106
}
115
- // patchFlag & dynamicPropNames
116
- if ( patchFlag !== 0 ) {
117
- if ( ! hasChildren ) {
118
- if ( ! hasProps ) {
119
- args . push ( `null` )
120
- }
121
- args . push ( `null` )
122
- }
123
- if ( __DEV__ ) {
124
- const flagNames = Object . keys ( PatchFlagNames )
125
- . map ( Number )
126
- . filter ( n => n > 0 && patchFlag & n )
127
- . map ( n => PatchFlagNames [ n ] )
128
- . join ( `, ` )
129
- args . push ( patchFlag + ` /* ${ flagNames } */` )
130
- } else {
131
- args . push ( patchFlag + '' )
132
- }
133
- if ( dynamicPropNames && dynamicPropNames . length ) {
134
- args . push (
135
- `[${ dynamicPropNames . map ( n => JSON . stringify ( n ) ) . join ( `, ` ) } ]`
136
- )
137
- }
107
+ // pass directly if the only child is a text node
108
+ // (plain / interpolation / expression)
109
+ if ( hasDynamicTextChild || type === NodeTypes . TEXT ) {
110
+ args . push ( child )
111
+ } else {
112
+ args . push ( node . children )
138
113
}
139
-
140
- const { loc } = node
141
- const vnode = createCallExpression (
142
- context . helper ( CREATE_VNODE ) ,
143
- args ,
144
- loc
114
+ } else {
115
+ args . push ( node . children )
116
+ }
117
+ }
118
+ // patchFlag & dynamicPropNames
119
+ if ( patchFlag !== 0 ) {
120
+ if ( ! hasChildren ) {
121
+ if ( ! hasProps ) {
122
+ args . push ( `null` )
123
+ }
124
+ args . push ( `null` )
125
+ }
126
+ if ( __DEV__ ) {
127
+ const flagNames = Object . keys ( PatchFlagNames )
128
+ . map ( Number )
129
+ . filter ( n => n > 0 && patchFlag & n )
130
+ . map ( n => PatchFlagNames [ n ] )
131
+ . join ( `, ` )
132
+ args . push ( patchFlag + ` /* ${ flagNames } */` )
133
+ } else {
134
+ args . push ( patchFlag + '' )
135
+ }
136
+ if ( dynamicPropNames && dynamicPropNames . length ) {
137
+ args . push (
138
+ `[${ dynamicPropNames . map ( n => JSON . stringify ( n ) ) . join ( `, ` ) } ]`
145
139
)
140
+ }
141
+ }
142
+
143
+ const { loc } = node
144
+ const vnode = createCallExpression ( context . helper ( CREATE_VNODE ) , args , loc )
146
145
147
- if ( runtimeDirectives && runtimeDirectives . length ) {
148
- node . codegenNode = createCallExpression (
149
- context . helper ( APPLY_DIRECTIVES ) ,
150
- [
151
- vnode ,
152
- createArrayExpression (
153
- runtimeDirectives . map ( dir => buildDirectiveArgs ( dir , context ) ) ,
154
- loc
155
- )
156
- ] ,
146
+ if ( runtimeDirectives && runtimeDirectives . length ) {
147
+ node . codegenNode = createCallExpression (
148
+ context . helper ( APPLY_DIRECTIVES ) ,
149
+ [
150
+ vnode ,
151
+ createArrayExpression (
152
+ runtimeDirectives . map ( dir => buildDirectiveArgs ( dir , context ) ) ,
157
153
loc
158
154
)
159
- } else {
160
- node . codegenNode = vnode
161
- }
162
- }
155
+ ] ,
156
+ loc
157
+ )
158
+ } else {
159
+ node . codegenNode = vnode
163
160
}
164
161
}
165
162
}
0 commit comments