1
1
import type { VueConstructor } from 'vue'
2
- import {
3
- ComponentInstance ,
4
- SetupContext ,
5
- SetupFunction ,
6
- Data ,
7
- } from './component'
2
+ import { ComponentInstance , SetupFunction , Data } from './component'
8
3
import { isRef , isReactive , toRefs , isRaw } from './reactivity'
9
4
import {
10
5
isPlainObject ,
@@ -24,7 +19,11 @@ import {
24
19
resolveScopedSlots ,
25
20
asVmProperty ,
26
21
} from './utils/instance'
27
- import { getVueConstructor } from './runtimeContext'
22
+ import {
23
+ getVueConstructor ,
24
+ SetupContext ,
25
+ toVue3ComponentInstance ,
26
+ } from './runtimeContext'
28
27
import { createObserver , reactive } from './reactivity/reactive'
29
28
30
29
export function mixin ( Vue : VueConstructor ) {
@@ -53,7 +52,9 @@ export function mixin(Vue: VueConstructor) {
53
52
if ( render ) {
54
53
// keep currentInstance accessible for createElement
55
54
$options . render = function ( ...args : any ) : any {
56
- return activateCurrentInstance ( vm , ( ) => render . apply ( this , args ) )
55
+ return activateCurrentInstance ( toVue3ComponentInstance ( vm ) , ( ) =>
56
+ render . apply ( this , args )
57
+ )
57
58
}
58
59
}
59
60
@@ -85,16 +86,17 @@ export function mixin(Vue: VueConstructor) {
85
86
function initSetup ( vm : ComponentInstance , props : Record < any , any > = { } ) {
86
87
const setup = vm . $options . setup !
87
88
const ctx = createSetupContext ( vm )
89
+ const instance = toVue3ComponentInstance ( vm )
90
+ instance . setupContext = ctx
88
91
89
92
// fake reactive for `toRefs(props)`
90
93
def ( props , '__ob__' , createObserver ( ) )
91
94
92
95
// resolve scopedSlots and slots to functions
93
- // @ts -expect-error
94
96
resolveScopedSlots ( vm , ctx . slots )
95
97
96
98
let binding : ReturnType < SetupFunction < Data , Data > > | undefined | null
97
- activateCurrentInstance ( vm , ( ) => {
99
+ activateCurrentInstance ( instance , ( ) => {
98
100
// make props to be fake reactive, this is for `toRefs(props)`
99
101
binding = setup ( props , ctx )
100
102
} )
@@ -105,9 +107,8 @@ export function mixin(Vue: VueConstructor) {
105
107
const bindingFunc = binding
106
108
// keep currentInstance accessible for createElement
107
109
vm . $options . render = ( ) => {
108
- // @ts -expect-error
109
110
resolveScopedSlots ( vm , ctx . slots )
110
- return activateCurrentInstance ( vm , ( ) => bindingFunc ( ) )
111
+ return activateCurrentInstance ( instance , ( ) => bindingFunc ( ) )
111
112
}
112
113
return
113
114
} else if ( isPlainObject ( binding ) ) {
@@ -228,23 +229,25 @@ export function mixin(Vue: VueConstructor) {
228
229
} )
229
230
} )
230
231
232
+ let propsProxy : any
231
233
propsReactiveProxy . forEach ( ( key ) => {
232
234
let srcKey = `$${ key } `
233
235
proxy ( ctx , key , {
234
236
get : ( ) => {
235
- const data = reactive ( { } )
237
+ if ( propsProxy ) return propsProxy
238
+ propsProxy = reactive ( { } )
236
239
const source = vm [ srcKey ]
237
240
238
241
for ( const attr of Object . keys ( source ) ) {
239
- proxy ( data , attr , {
242
+ proxy ( propsProxy , attr , {
240
243
get : ( ) => {
241
244
// to ensure it always return the latest value
242
245
return vm [ srcKey ] [ attr ]
243
246
} ,
244
247
} )
245
248
}
246
249
247
- return data
250
+ return propsProxy
248
251
} ,
249
252
set ( ) {
250
253
__DEV__ &&
0 commit comments