From 27873dbe1c09ac6a058d815949a4e13831513fd0 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 25 Mar 2020 09:28:37 -0400 Subject: [PATCH] feat(runtime-core): support app.config.globalProperties per https://github.com/vuejs/rfcs/pull/117/ --- .../__tests__/apiCreateApp.spec.ts | 34 +++++++++++++++++++ .../runtime-core/__tests__/apiOptions.spec.ts | 22 ------------ packages/runtime-core/src/apiCreateApp.ts | 2 ++ packages/runtime-core/src/componentProxy.ts | 21 +++++++++--- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/packages/runtime-core/__tests__/apiCreateApp.spec.ts b/packages/runtime-core/__tests__/apiCreateApp.spec.ts index d43b660d..fbc784f4 100644 --- a/packages/runtime-core/__tests__/apiCreateApp.spec.ts +++ b/packages/runtime-core/__tests__/apiCreateApp.spec.ts @@ -440,4 +440,38 @@ describe('api: createApp', () => { ).toHaveBeenWarned() }) }) + + test('config.optionMergeStrategies', () => { + let merged: string + const App = defineComponent({ + render() {}, + mixins: [{ foo: 'mixin' }], + extends: { foo: 'extends' }, + foo: 'local', + beforeCreate() { + merged = this.$options.foo + } + }) + + const app = createApp(App) + app.mixin({ + foo: 'global' + }) + app.config.optionMergeStrategies.foo = (a, b) => (a ? `${a},` : ``) + b + + app.mount(nodeOps.createElement('div')) + expect(merged!).toBe('global,extends,mixin,local') + }) + + test('config.globalProperties', () => { + const app = createApp({ + render() { + return this.foo + } + }) + app.config.globalProperties.foo = 'hello' + const root = nodeOps.createElement('div') + app.mount(root) + expect(serializeInner(root)).toBe('hello') + }) }) diff --git a/packages/runtime-core/__tests__/apiOptions.spec.ts b/packages/runtime-core/__tests__/apiOptions.spec.ts index 379d15db..3a34c966 100644 --- a/packages/runtime-core/__tests__/apiOptions.spec.ts +++ b/packages/runtime-core/__tests__/apiOptions.spec.ts @@ -563,28 +563,6 @@ describe('api: options', () => { expect(serializeInner(root)).toBe(`
1,1,3
`) }) - test('optionMergeStrategies', () => { - let merged: string - const App = defineComponent({ - render() {}, - mixins: [{ foo: 'mixin' }], - extends: { foo: 'extends' }, - foo: 'local', - beforeCreate() { - merged = this.$options.foo - } - }) - - const app = createApp(App) - app.mixin({ - foo: 'global' - }) - app.config.optionMergeStrategies.foo = (a, b) => (a ? `${a},` : ``) + b - - app.mount(nodeOps.createElement('div')) - expect(merged!).toBe('global,extends,mixin,local') - }) - describe('warnings', () => { mockWarn() diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index 7c63f0b0..2f76d6b4 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -50,6 +50,7 @@ export interface AppConfig { devtools: boolean performance: boolean optionMergeStrategies: Record + globalProperties: Record isCustomElement: (tag: string) => boolean errorHandler?: ( err: unknown, @@ -86,6 +87,7 @@ export function createAppContext(): AppContext { isNativeTag: NO, devtools: true, performance: false, + globalProperties: {}, optionMergeStrategies: {}, isCustomElement: NO, errorHandler: undefined, diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index e40fb801..ce2261d7 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -77,7 +77,15 @@ const enum AccessTypes { export const PublicInstanceProxyHandlers: ProxyHandler = { get(target: ComponentInternalInstance, key: string) { - const { renderContext, data, propsProxy, accessCache, type, sink } = target + const { + renderContext, + data, + propsProxy, + accessCache, + type, + sink, + appContext + } = target // data / props / renderContext // This getter gets called for every property access on the render context @@ -118,19 +126,24 @@ export const PublicInstanceProxyHandlers: ProxyHandler = { // public $xxx properties & user-attached properties (sink) const publicGetter = publicPropertiesMap[key] - let cssModule + let cssModule, globalProperties if (publicGetter) { if (__DEV__ && key === '$attrs') { markAttrsAccessed() } return publicGetter(target) + } else if (hasOwn(sink, key)) { + return sink[key] } else if ( (cssModule = type.__cssModules) && (cssModule = cssModule[key]) ) { return cssModule - } else if (hasOwn(sink, key)) { - return sink[key] + } else if ( + ((globalProperties = appContext.config.globalProperties), + hasOwn(globalProperties, key)) + ) { + return globalProperties[key] } else if (__DEV__ && currentRenderingInstance) { warn( `Property ${JSON.stringify(key)} was accessed during render ` +