Skip to content

Commit 5a599d6

Browse files
committed
fix: should be called with the current instance and current scope
1 parent b1c8f9f commit 5a599d6

File tree

5 files changed

+53
-11
lines changed

5 files changed

+53
-11
lines changed

packages/runtime-vapor/__tests__/dom/prop.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ import {
1414
setCurrentInstance,
1515
} from '../../src/component'
1616
import { getMetadata, recordPropMetadata } from '../../src/componentMetadata'
17+
import { getCurrentScope } from '@vue/reactivity'
1718

1819
let removeComponentInstance = NOOP
1920
beforeEach(() => {
2021
const instance = createComponentInstance((() => {}) as any, {})
2122
const reset = setCurrentInstance(instance)
23+
const prev = getCurrentScope()
2224
instance.scope.on()
2325
removeComponentInstance = () => {
26+
instance.scope.prevScope = prev
2427
instance.scope.off()
2528
reset()
2629
removeComponentInstance = NOOP

packages/runtime-vapor/__tests__/renderEffect.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import {
2+
EffectScope,
3+
getCurrentScope,
24
nextTick,
35
onBeforeUpdate,
46
onEffectCleanup,
@@ -10,6 +12,10 @@ import {
1012
watchPostEffect,
1113
watchSyncEffect,
1214
} from '../src'
15+
import {
16+
type ComponentInternalInstance,
17+
currentInstance,
18+
} from '../src/component'
1319
import { makeRender } from './_utils'
1420

1521
const define = makeRender<any>()
@@ -207,4 +213,27 @@ describe('renderEffect', () => {
207213
'[Vue warn] Unhandled error during execution of updated',
208214
).toHaveBeenWarned()
209215
})
216+
217+
test('should be called with the current instance and current scope', async () => {
218+
const source = ref(0)
219+
const scope = new EffectScope()
220+
let instanceSnap: ComponentInternalInstance | null = null
221+
let scopeSnap: EffectScope | undefined = undefined
222+
const { instance } = define(() => {
223+
scope.run(() => {
224+
renderEffect(() => {
225+
instanceSnap = currentInstance
226+
scopeSnap = getCurrentScope()
227+
})
228+
})
229+
}).render()
230+
231+
expect(instanceSnap).toBe(instance)
232+
expect(scopeSnap).toBe(scope)
233+
234+
source.value++
235+
await nextTick()
236+
expect(instanceSnap).toBe(instance)
237+
expect(scopeSnap).toBe(scope)
238+
})
210239
})

packages/runtime-vapor/src/componentLifecycle.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ export function invokeLifecycle(
1717
if (hooks) {
1818
const fn = () => {
1919
const reset = setCurrentInstance(instance)
20-
instance.scope.run(() => {
21-
invokeArrayFns(hooks)
22-
})
20+
instance.scope.run(() => invokeArrayFns(hooks))
2321
reset()
2422
}
2523
post ? queuePostRenderEffect(fn) : fn()

packages/runtime-vapor/src/componentProps.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,7 @@ function resolvePropValue(
212212
// value = propsDefaults[key]
213213
// } else {
214214
const reset = setCurrentInstance(instance)
215-
instance.scope.run(() => {
216-
value = defaultValue.call(null, props)
217-
})
215+
instance.scope.run(() => (value = defaultValue.call(null, props)))
218216
reset()
219217
// }
220218
} else {

packages/runtime-vapor/src/renderEffect.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
ReactiveEffect,
44
type SchedulerJob,
55
SchedulerJobFlags,
6+
getCurrentScope,
67
} from '@vue/reactivity'
78
import { invokeArrayFns } from '@vue/shared'
89
import {
@@ -16,6 +17,7 @@ import { invokeDirectiveHook } from './directives'
1617

1718
export function renderEffect(cb: () => void) {
1819
const instance = getCurrentInstance()
20+
const scope = getCurrentScope()
1921

2022
let effect: ReactiveEffect
2123

@@ -53,11 +55,23 @@ export function renderEffect(cb: () => void) {
5355
}
5456
}
5557

56-
effect = new ReactiveEffect(() => {
57-
const reset = instance && setCurrentInstance(instance)
58-
callWithAsyncErrorHandling(cb, instance, VaporErrorCodes.RENDER_FUNCTION)
59-
reset?.()
60-
})
58+
if (scope) {
59+
const baseCb = cb
60+
cb = () => scope.run(baseCb)
61+
}
62+
63+
if (instance) {
64+
const baseCb = cb
65+
cb = () => {
66+
const reset = setCurrentInstance(instance)
67+
baseCb()
68+
reset()
69+
}
70+
}
71+
72+
effect = new ReactiveEffect(() =>
73+
callWithAsyncErrorHandling(cb, instance, VaporErrorCodes.RENDER_FUNCTION),
74+
)
6175

6276
effect.scheduler = () => {
6377
if (instance) job.id = instance.uid

0 commit comments

Comments
 (0)