Skip to content

Commit 5510ce3

Browse files
authored
feat: hasInjectionContext() for libraries (#8111)
1 parent 2f9f6ec commit 5510ce3

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

packages/runtime-core/__tests__/apiInject.spec.ts

+29-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import {
88
Ref,
99
readonly,
1010
reactive,
11-
defineComponent
11+
defineComponent,
12+
hasInjectionContext
1213
} from '../src/index'
13-
import { render, nodeOps, serialize } from '@vue/runtime-test'
14+
import { render, nodeOps, serialize, createApp } from '@vue/runtime-test'
1415

1516
// reference: https://vue-composition-api-rfc.netlify.com/api.html#provide-inject
1617
describe('api: provide/inject', () => {
@@ -347,4 +348,30 @@ describe('api: provide/inject', () => {
347348
render(h(Comp), root)
348349
expect(serialize(root)).toBe(`<div><!----></div>`)
349350
})
351+
352+
describe('hasInjectionContext', () => {
353+
it('should be false outside of setup', () => {
354+
expect(hasInjectionContext()).toBe(false)
355+
})
356+
357+
it('should be true within setup', () => {
358+
expect.assertions(1)
359+
const Comp = {
360+
setup() {
361+
expect(hasInjectionContext()).toBe(true)
362+
return () => null
363+
}
364+
}
365+
366+
const root = nodeOps.createElement('div')
367+
render(h(Comp), root)
368+
})
369+
370+
it('should be true within app.runWithContext()', () => {
371+
expect.assertions(1)
372+
createApp({}).runWithContext(() => {
373+
expect(hasInjectionContext()).toBe(true)
374+
})
375+
})
376+
})
350377
})

packages/runtime-core/src/apiInject.ts

+9
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,12 @@ export function inject(
7373
warn(`inject() can only be used inside setup() or functional components.`)
7474
}
7575
}
76+
77+
/**
78+
* Returns true if `inject()` can be used without warning about being called in the wrong place (e.g. outside of
79+
* setup()). This is used by libraries that want to use `inject()` internally without triggering a warning to the end
80+
* user. One example is `useRoute()` in `vue-router`.
81+
*/
82+
export function hasInjectionContext(): boolean {
83+
return !!(currentInstance || currentRenderingInstance || currentApp)
84+
}

packages/runtime-core/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export {
5656
onErrorCaptured,
5757
onServerPrefetch
5858
} from './apiLifecycle'
59-
export { provide, inject } from './apiInject'
59+
export { provide, inject, hasInjectionContext } from './apiInject'
6060
export { nextTick } from './scheduler'
6161
export { defineComponent } from './apiDefineComponent'
6262
export { defineAsyncComponent } from './apiAsyncComponent'

0 commit comments

Comments
 (0)