Skip to content

Commit 324e817

Browse files
committed
dx(computed): warn incorrect use of getCurrentInstance inside computed
ref #9974 close #10001
1 parent 2701355 commit 324e817

File tree

3 files changed

+92
-5
lines changed

3 files changed

+92
-5
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {
2+
computed,
3+
getCurrentInstance,
4+
h,
5+
nodeOps,
6+
render,
7+
} from '@vue/runtime-test'
8+
9+
describe('api: computed', () => {
10+
test('should warn if getCurrentInstance is called inside computed getter', () => {
11+
const Comp = {
12+
setup() {
13+
const c = computed(() => {
14+
getCurrentInstance()
15+
return 1
16+
})
17+
return () => c.value
18+
},
19+
}
20+
render(h(Comp), nodeOps.createElement('div'))
21+
expect(
22+
'getCurrentInstance() called inside a computed getter',
23+
).toHaveBeenWarned()
24+
})
25+
26+
test('should warn if getCurrentInstance is called inside computed getter (object syntax)', () => {
27+
const Comp = {
28+
setup() {
29+
const c = computed({
30+
get: () => {
31+
getCurrentInstance()
32+
return 1
33+
},
34+
set: () => {},
35+
})
36+
return () => c.value
37+
},
38+
}
39+
render(h(Comp), nodeOps.createElement('div'))
40+
expect(
41+
'getCurrentInstance() called inside a computed getter',
42+
).toHaveBeenWarned()
43+
})
44+
})
Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,42 @@
1-
import { computed as _computed } from '@vue/reactivity'
1+
import {
2+
type ComputedGetter,
3+
type WritableComputedOptions,
4+
computed as _computed,
5+
} from '@vue/reactivity'
26
import { isInSSRComponentSetup } from './component'
7+
import { isFunction } from '@vue/shared'
8+
9+
/**
10+
* For dev warning only.
11+
* Context: https://github.com/vuejs/core/discussions/9974
12+
*/
13+
export let isInComputedGetter = false
14+
15+
function wrapComputedGetter(
16+
getter: ComputedGetter<unknown>,
17+
): ComputedGetter<unknown> {
18+
return () => {
19+
isInComputedGetter = true
20+
try {
21+
return getter()
22+
} finally {
23+
isInComputedGetter = false
24+
}
25+
}
26+
}
327

428
export const computed: typeof _computed = (
5-
getterOrOptions: any,
29+
getterOrOptions: ComputedGetter<unknown> | WritableComputedOptions<unknown>,
630
debugOptions?: any,
731
) => {
8-
// @ts-expect-error
32+
if (__DEV__) {
33+
if (isFunction(getterOrOptions)) {
34+
getterOrOptions = wrapComputedGetter(getterOrOptions)
35+
} else {
36+
getterOrOptions.get = wrapComputedGetter(getterOrOptions.get)
37+
}
38+
}
39+
40+
// @ts-expect-error the 3rd argument is hidden from public types
941
return _computed(getterOrOptions, debugOptions, isInSSRComponentSetup)
1042
}

packages/runtime-core/src/component.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ import {
8585
} from './compat/compatConfig'
8686
import type { SchedulerJob } from './scheduler'
8787
import type { LifecycleHooks } from './enums'
88+
import { isInComputedGetter } from './apiComputed'
8889

8990
export type Data = Record<string, unknown>
9091

@@ -631,8 +632,18 @@ export function createComponentInstance(
631632

632633
export let currentInstance: ComponentInternalInstance | null = null
633634

634-
export const getCurrentInstance: () => ComponentInternalInstance | null = () =>
635-
currentInstance || currentRenderingInstance
635+
export const getCurrentInstance: () => ComponentInternalInstance | null =
636+
() => {
637+
if (__DEV__ && isInComputedGetter) {
638+
warn(
639+
`getCurrentInstance() called inside a computed getter. ` +
640+
`This is incorrect usage as computed getters are not guaranteed ` +
641+
`to be executed with an active component instance. If you are using ` +
642+
`a composable inside a computed getter, move it ouside to the setup scope.`,
643+
)
644+
}
645+
return currentInstance || currentRenderingInstance
646+
}
636647

637648
let internalSetCurrentInstance: (
638649
instance: ComponentInternalInstance | null,

0 commit comments

Comments
 (0)