@@ -29,6 +29,8 @@ import {
29
29
} from '../vnode'
30
30
import { checkCompatEnabled , DeprecationTypes } from './compatConfig'
31
31
32
+ const v3CompiledRenderFnRE = / ^ (?: f u n c t i o n \w + ) ? \( _ c t x , _ c a c h e /
33
+
32
34
export function convertLegacyRenderFn ( instance : ComponentInternalInstance ) {
33
35
const Component = instance . type as ComponentOptions
34
36
const render = Component . render as InternalRenderFunction | undefined
@@ -38,8 +40,7 @@ export function convertLegacyRenderFn(instance: ComponentInternalInstance) {
38
40
return
39
41
}
40
42
41
- const string = render . toString ( )
42
- if ( string . startsWith ( 'function render(_ctx' ) || string . startsWith ( '(_ctx' ) ) {
43
+ if ( v3CompiledRenderFnRE . test ( render . toString ( ) ) ) {
43
44
// v3 pre-compiled function
44
45
render . _compatChecked = true
45
46
return
@@ -128,9 +129,7 @@ export function compatH(
128
129
return convertLegacySlots ( createVNode ( type , null , propsOrChildren ) )
129
130
}
130
131
} else {
131
- if ( l > 3 ) {
132
- children = Array . prototype . slice . call ( arguments , 2 )
133
- } else if ( l === 3 && isVNode ( children ) ) {
132
+ if ( isVNode ( children ) ) {
134
133
children = [ children ]
135
134
}
136
135
return convertLegacySlots (
@@ -157,13 +156,20 @@ function convertLegacyProps(
157
156
} else if ( key === 'on' || key === 'nativeOn' ) {
158
157
const listeners = legacyProps [ key ]
159
158
for ( const event in listeners ) {
160
- const handlerKey = toHandlerKey ( event )
159
+ const handlerKey = convertLegacyEventKey ( event )
161
160
const existing = converted [ handlerKey ]
162
161
const incoming = listeners [ event ]
163
162
if ( existing !== incoming ) {
164
- converted [ handlerKey ] = existing
165
- ? [ ] . concat ( existing as any , incoming as any )
166
- : incoming
163
+ if ( existing ) {
164
+ // for the rare case where the same handler is attached
165
+ // twice with/without .native modifier...
166
+ if ( key === 'nativeOn' && String ( existing ) === String ( incoming ) ) {
167
+ continue
168
+ }
169
+ converted [ handlerKey ] = [ ] . concat ( existing as any , incoming as any )
170
+ } else {
171
+ converted [ handlerKey ] = incoming
172
+ }
167
173
}
168
174
}
169
175
} else if (
@@ -185,6 +191,20 @@ function convertLegacyProps(
185
191
return converted
186
192
}
187
193
194
+ function convertLegacyEventKey ( event : string ) : string {
195
+ // normalize v2 event prefixes
196
+ if ( event [ 0 ] === '&' ) {
197
+ event = event . slice ( 1 ) + 'Passive'
198
+ }
199
+ if ( event [ 0 ] === '~' ) {
200
+ event = event . slice ( 1 ) + 'Once'
201
+ }
202
+ if ( event [ 0 ] === '!' ) {
203
+ event = event . slice ( 1 ) + 'Capture'
204
+ }
205
+ return toHandlerKey ( event )
206
+ }
207
+
188
208
function convertLegacyDirectives (
189
209
vnode : VNode ,
190
210
props ?: LegacyVNodeProps
0 commit comments