@@ -3,7 +3,7 @@ import { camelize } from '@vue/shared';
3
3
import { minimatch } from 'minimatch' ;
4
4
import type { Code , VueCodeInformation , VueCompilerOptions } from '../../types' ;
5
5
import { hyphenateAttr , hyphenateTag } from '../../utils/shared' ;
6
- import { conditionWrapWith , newLine , variableNameRegex , wrapWith } from '../common' ;
6
+ import { conditionWrapWith , variableNameRegex , wrapWith } from '../common' ;
7
7
import { generateCamelized } from './camelized' ;
8
8
import type { TemplateCodegenContext } from './context' ;
9
9
import type { TemplateCodegenOptions } from './index' ;
@@ -20,23 +20,9 @@ export function* generateElementProps(
20
20
enableCodeFeatures : boolean ,
21
21
propsFailedExps ?: CompilerDOM . SimpleExpressionNode [ ] ,
22
22
) : Generator < Code > {
23
- let styleAttrNum = 0 ;
24
- let classAttrNum = 0 ;
25
-
26
23
const isIntrinsicElement = node . tagType === CompilerDOM . ElementTypes . ELEMENT || node . tagType === CompilerDOM . ElementTypes . TEMPLATE ;
27
24
const canCamelize = node . tagType === CompilerDOM . ElementTypes . COMPONENT ;
28
25
29
- if ( props . some ( prop =>
30
- prop . type === CompilerDOM . NodeTypes . DIRECTIVE
31
- && prop . name === 'bind'
32
- && ! prop . arg
33
- && prop . exp ?. type === CompilerDOM . NodeTypes . SIMPLE_EXPRESSION
34
- ) ) {
35
- // fix https://github.com/vuejs/language-tools/issues/2166
36
- styleAttrNum ++ ;
37
- classAttrNum ++ ;
38
- }
39
-
40
26
if ( isIntrinsicElement ) {
41
27
for ( const prop of props ) {
42
28
if (
@@ -46,10 +32,11 @@ export function* generateElementProps(
46
32
&& ! prop . arg . loc . source . startsWith ( '[' )
47
33
&& ! prop . arg . loc . source . endsWith ( ']' )
48
34
) {
35
+ yield `...{ ` ;
49
36
yield * generateEventArg ( ctx , prop . arg , true ) ;
50
37
yield `: ` ;
51
38
yield * generateEventExpression ( options , ctx , prop ) ;
52
- yield `, ${ newLine } ` ;
39
+ yield `}, ` ;
53
40
}
54
41
else if (
55
42
prop . type === CompilerDOM . NodeTypes . DIRECTIVE
@@ -69,26 +56,17 @@ export function* generateElementProps(
69
56
}
70
57
}
71
58
else {
72
- let generatedEvent = false ;
73
59
for ( const prop of props ) {
74
60
if (
75
61
prop . type === CompilerDOM . NodeTypes . DIRECTIVE
76
62
&& prop . name === 'on'
77
63
&& prop . arg ?. type === CompilerDOM . NodeTypes . SIMPLE_EXPRESSION
64
+ && ! prop . arg . loc . source . startsWith ( '[' )
65
+ && ! prop . arg . loc . source . endsWith ( ']' )
78
66
) {
79
- if ( prop . arg . loc . source . startsWith ( '[' ) && prop . arg . loc . source . endsWith ( ']' ) ) {
80
- continue ;
81
- }
82
- if ( ! generatedEvent ) {
83
- yield `...{ ` ;
84
- generatedEvent = true ;
85
- }
86
- yield `'${ camelize ( 'on-' + prop . arg . loc . source ) } ': {} as any, ` ;
67
+ yield `...{ '${ camelize ( 'on-' + prop . arg . loc . source ) } ': {} as any }, ` ;
87
68
}
88
69
}
89
- if ( generatedEvent ) {
90
- yield `}, ` ;
91
- }
92
70
}
93
71
94
72
for ( const prop of props ) {
@@ -105,28 +83,29 @@ export function* generateElementProps(
105
83
: prop . arg . loc . source
106
84
: getModelValuePropName ( node , options . vueCompilerOptions . target , options . vueCompilerOptions ) ;
107
85
108
- if ( prop . modifiers . some ( m => m === 'prop' || m === 'attr' ) ) {
109
- propName = propName ?. substring ( 1 ) ;
110
- }
111
-
112
86
if (
113
87
propName === undefined
114
- || options . vueCompilerOptions . dataAttributes . some ( pattern => minimatch ( propName , pattern ) )
115
- || ( propName === 'style' && ++ styleAttrNum >= 2 )
116
- || ( propName === 'class' && ++ classAttrNum >= 2 )
117
- || ( propName === 'name' && node . tagType === CompilerDOM . ElementTypes . SLOT ) // #2308
88
+ || options . vueCompilerOptions . dataAttributes . some ( pattern => minimatch ( propName ! , pattern ) )
118
89
) {
119
90
if ( prop . exp && prop . exp . constType !== CompilerDOM . ConstantTypes . CAN_STRINGIFY ) {
120
91
propsFailedExps ?. push ( prop . exp ) ;
121
92
}
122
93
continue ;
123
94
}
124
95
96
+ if ( prop . modifiers . some ( m => m === 'prop' || m === 'attr' ) ) {
97
+ propName = propName . substring ( 1 ) ;
98
+ }
99
+
100
+ const shouldSpread = propName === 'style' || propName === 'class' ;
125
101
const shouldCamelize = canCamelize
126
102
&& ( ! prop . arg || ( prop . arg . type === CompilerDOM . NodeTypes . SIMPLE_EXPRESSION && prop . arg . isStatic ) ) // isStatic
127
103
&& hyphenateAttr ( propName ) === propName
128
104
&& ! options . vueCompilerOptions . htmlAttributes . some ( pattern => minimatch ( propName , pattern ) ) ;
129
105
106
+ if ( shouldSpread ) {
107
+ yield `...{ ` ;
108
+ }
130
109
const codes = wrapWith (
131
110
prop . loc . start . offset ,
132
111
prop . loc . end . offset ,
@@ -169,31 +148,32 @@ export function* generateElementProps(
169
148
else {
170
149
yield * codes ;
171
150
}
151
+ if ( shouldSpread ) {
152
+ yield ` }` ;
153
+ }
172
154
yield `, ` ;
173
155
}
174
156
else if ( prop . type === CompilerDOM . NodeTypes . ATTRIBUTE ) {
175
157
if (
176
158
options . vueCompilerOptions . dataAttributes . some ( pattern => minimatch ( prop . name , pattern ) )
177
- || ( prop . name === 'style' && ++ styleAttrNum >= 2 )
178
- || ( prop . name === 'class' && ++ classAttrNum >= 2 )
179
- || ( prop . name === 'name' && node . tagType === CompilerDOM . ElementTypes . SLOT ) // #2308
180
- ) {
181
- continue ;
182
- }
183
-
184
- if (
185
- options . vueCompilerOptions . target < 3
186
- && prop . name === 'persisted'
187
- && node . tag . toLowerCase ( ) === 'transition'
188
- ) {
189
159
// Vue 2 Transition doesn't support "persisted" property but `@vue/compiler-dom always adds it (#3881)
160
+ || (
161
+ options . vueCompilerOptions . target < 3
162
+ && prop . name === 'persisted'
163
+ && node . tag . toLowerCase ( ) === 'transition'
164
+ )
165
+ ) {
190
166
continue ;
191
167
}
192
168
169
+ const shouldSpread = prop . name === 'style' || prop . name === 'class' ;
193
170
const shouldCamelize = canCamelize
194
171
&& hyphenateAttr ( prop . name ) === prop . name
195
172
&& ! options . vueCompilerOptions . htmlAttributes . some ( pattern => minimatch ( prop . name , pattern ) ) ;
196
173
174
+ if ( shouldSpread ) {
175
+ yield `...{ ` ;
176
+ }
197
177
const codes = conditionWrapWith (
198
178
enableCodeFeatures ,
199
179
prop . loc . start . offset ,
@@ -232,6 +212,9 @@ export function* generateElementProps(
232
212
else {
233
213
yield * codes ;
234
214
}
215
+ if ( shouldSpread ) {
216
+ yield ` }` ;
217
+ }
235
218
yield `, ` ;
236
219
}
237
220
else if (
0 commit comments