From d167b9b41e74729337596b201690b2280d18cc93 Mon Sep 17 00:00:00 2001 From: lsdsjy Date: Fri, 24 Jun 2022 17:49:02 +0800 Subject: [PATCH] feat: support Vue3 style app-level provide (#945) --- src/apis/createApp.ts | 14 +++++++++++++- test/createApp.spec.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/apis/createApp.ts b/src/apis/createApp.ts index 4c86dde9..8f3aa208 100644 --- a/src/apis/createApp.ts +++ b/src/apis/createApp.ts @@ -3,6 +3,7 @@ import { VueConstructor } from 'vue' import { Directive } from '../component/directives' import { getVueConstructor } from '../runtimeContext' import { warn } from '../utils' +import { InjectionKey } from './inject' // Has a generic to match Vue 3 API and be type compatible export interface App { @@ -12,6 +13,7 @@ export interface App { component: VueConstructor['component'] directive(name: string): Directive | undefined directive(name: string, directive: Directive): this + provide(key: InjectionKey | symbol | string, value: T): this mount: Vue['$mount'] unmount: Vue['$destroy'] } @@ -21,11 +23,17 @@ export function createApp(rootComponent: any, rootProps: any = undefined): App { let mountedVM: Vue | undefined = undefined + let provide: Record = {} + const app: App = { config: V.config, use: V.use.bind(V), mixin: V.mixin.bind(V), component: V.component.bind(V), + provide(key: InjectionKey | symbol | string, value: T) { + provide[key as any] = value + return this + }, directive(name: string, dir?: Directive | undefined): any { if (dir) { V.directive(name, dir as any) @@ -36,7 +44,11 @@ export function createApp(rootComponent: any, rootProps: any = undefined): App { }, mount: (el, hydrating) => { if (!mountedVM) { - mountedVM = new V({ propsData: rootProps, ...rootComponent }) + mountedVM = new V({ + propsData: rootProps, + ...rootComponent, + provide: { ...provide, ...rootComponent.provide }, + }) mountedVM.$mount(el, hydrating) return mountedVM } else { diff --git a/test/createApp.spec.ts b/test/createApp.spec.ts index 3c3419a8..097a52c9 100644 --- a/test/createApp.spec.ts +++ b/test/createApp.spec.ts @@ -62,4 +62,45 @@ describe('createApp', () => { await nextTick() expect(vm.$el.textContent).toBe('foobar') }) + + it('should work with provide', async () => { + const Foo = defineComponent({ + inject: ['msg'], + template: '

{{msg}}

', + }) + + const app = createApp( + defineComponent({ + template: '', + components: { Foo }, + }) + ) + app.provide('msg', 'foobar') + const vm = app.mount() + + await nextTick() + expect(vm.$el.textContent).toBe('foobar') + }) + + it("should respect root component's provide", async () => { + const Foo = defineComponent({ + inject: ['msg'], + template: '

{{msg}}

', + }) + + const app = createApp( + defineComponent({ + template: '', + provide: { + msg: 'root component', + }, + components: { Foo }, + }) + ) + app.provide('msg', 'application') + const vm = app.mount() + + await nextTick() + expect(vm.$el.textContent).toBe('root component') + }) })