From: skirtle <65301168+skirtles-code@users.noreply.github.com> Date: Mon, 24 Nov 2025 06:54:12 +0000 (+0000) Subject: fix(provide): warn when using `provide` after mounting (#13954) X-Git-Tag: v3.5.25~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=247b2c2067afc4dee52f9f7bc194f3aab347ac55;p=thirdparty%2Fvuejs%2Fcore.git fix(provide): warn when using `provide` after mounting (#13954) close #13921 close #13924 --- diff --git a/packages/runtime-core/__tests__/apiInject.spec.ts b/packages/runtime-core/__tests__/apiInject.spec.ts index e5c9267e5b..27dc9677f1 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 d5c97a52b8..af59984fe0 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