diff --git a/packages/runtime-core/__tests__/apiInject.spec.ts b/packages/runtime-core/__tests__/apiInject.spec.ts index e5c9267e5bb..27dc9677f1b 100644 --- a/packages/runtime-core/__tests__/apiInject.spec.ts +++ b/packages/runtime-core/__tests__/apiInject.spec.ts @@ -6,6 +6,7 @@ import { hasInjectionContext, inject, nextTick, + onMounted, provide, reactive, readonly, @@ -372,4 +373,46 @@ describe('api: provide/inject', () => { }) }) }) + + describe('warnings for incorrect usage', () => { + it('should warn when inject() is called outside setup', () => { + inject('foo', 'bar') + expect(`inject() can only be used`).toHaveBeenWarned() + }) + + it('should warn when provide() is called outside setup', () => { + provide('foo', 'bar') + expect(`provide() can only be used`).toHaveBeenWarned() + }) + + it('should warn when provide() is called from a render function', () => { + const Provider = { + setup() { + return () => { + provide('foo', 'bar') + } + }, + } + + const root = nodeOps.createElement('div') + render(h(Provider), root) + expect(`provide() can only be used`).toHaveBeenWarned() + }) + + it('should warn when provide() is called from onMounted', () => { + const Provider = { + setup() { + onMounted(() => { + provide('foo', 'bar') + }) + + return () => null + }, + } + + const root = nodeOps.createElement('div') + render(h(Provider), root) + expect(`provide() can only be used`).toHaveBeenWarned() + }) + }) }) diff --git a/packages/runtime-core/src/apiInject.ts b/packages/runtime-core/src/apiInject.ts index d5c97a52b83..af59984fe00 100644 --- a/packages/runtime-core/src/apiInject.ts +++ b/packages/runtime-core/src/apiInject.ts @@ -11,11 +11,12 @@ export function provide | string | number>( key: K, value: K extends InjectionKey ? V : T, ): void { - if (!currentInstance) { - if (__DEV__) { + if (__DEV__) { + if (!currentInstance || currentInstance.isMounted) { warn(`provide() can only be used inside setup().`) } - } else { + } + if (currentInstance) { let provides = currentInstance.provides // by default an instance inherits its parent's provides object // but when it needs to provide values of its own, it creates its