Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: hasInjectionContext() for libraries #8111

Merged
merged 1 commit into from Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 29 additions & 2 deletions packages/runtime-core/__tests__/apiInject.spec.ts
Expand Up @@ -8,9 +8,10 @@ import {
Ref,
readonly,
reactive,
defineComponent
defineComponent,
hasInjectionContext
} from '../src/index'
import { render, nodeOps, serialize } from '@vue/runtime-test'
import { render, nodeOps, serialize, createApp } from '@vue/runtime-test'

// reference: https://vue-composition-api-rfc.netlify.com/api.html#provide-inject
describe('api: provide/inject', () => {
Expand Down Expand Up @@ -347,4 +348,30 @@ describe('api: provide/inject', () => {
render(h(Comp), root)
expect(serialize(root)).toBe(`<div><!----></div>`)
})

describe('hasInjectionContext', () => {
it('should be false outside of setup', () => {
expect(hasInjectionContext()).toBe(false)
})

it('should be true within setup', () => {
expect.assertions(1)
const Comp = {
setup() {
expect(hasInjectionContext()).toBe(true)
return () => null
}
}

const root = nodeOps.createElement('div')
render(h(Comp), root)
})

it('should be true within app.runWithContext()', () => {
expect.assertions(1)
createApp({}).runWithContext(() => {
expect(hasInjectionContext()).toBe(true)
})
})
})
})
9 changes: 9 additions & 0 deletions packages/runtime-core/src/apiInject.ts
Expand Up @@ -73,3 +73,12 @@ export function inject(
warn(`inject() can only be used inside setup() or functional components.`)
}
}

/**
* Returns true if `inject()` can be used without warning about being called in the wrong place (e.g. outside of
* setup()). This is used by libraries that want to use `inject()` internally without triggering a warning to the end
* user. One example is `useRoute()` in `vue-router`.
*/
export function hasInjectionContext(): boolean {
return !!(currentInstance || currentRenderingInstance || currentApp)
}
2 changes: 1 addition & 1 deletion packages/runtime-core/src/index.ts
Expand Up @@ -56,7 +56,7 @@ export {
onErrorCaptured,
onServerPrefetch
} from './apiLifecycle'
export { provide, inject } from './apiInject'
export { provide, inject, hasInjectionContext } from './apiInject'
export { nextTick } from './scheduler'
export { defineComponent } from './apiDefineComponent'
export { defineAsyncComponent } from './apiAsyncComponent'
Expand Down