From 0ea128a6fbaf766be72a93eef6d956fd26e50de6 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Fri, 17 Apr 2020 10:14:03 +0200 Subject: [PATCH 1/5] feat(runtime-core): add ComponentCustomProperties interface --- packages/runtime-core/src/componentProxy.ts | 31 +++++++++++++++++++- packages/runtime-core/src/index.ts | 5 +++- test-dts/componentCustomProperties.test-d.ts | 20 +++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 test-dts/componentCustomProperties.test-d.ts diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index 03044d07f4e..917bcebc89c 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -24,6 +24,34 @@ import { } from './componentRenderUtils' import { warn } from './warning' +// +/** + * Custom properties added to component instances in any way and can be accessed through `this` + * + * @example + * Here is an example of adding a property `$router` to every component instance: + * ```ts + * import { createApp } from 'vue' + * import { Router, createRouter } from 'vue-router' + * + * declare module '@vue/runtime-core' { + * interface ComponentCustomProperties { + * $router: Router + * } + * } + * + * // effectively adding the router to every component instance + * const app = createApp({}) + * const router = createRouter() + * app.config.globalProperties.$router = router + * + * const vm = app.mount('#app') + * // we cann access the router from the instance + * vm.$router.push('/') + * ``` + */ +export interface ComponentCustomProperties {} + // public properties exposed on the proxy, which is used as the render context // in templates (as `this` in the render option) export type ComponentPublicInstance< @@ -53,7 +81,8 @@ export type ComponentPublicInstance< UnwrapRef & D & ExtractComputedReturns & - M + M & + ComponentCustomProperties const publicPropertiesMap: Record< string, diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 5a855e378ac..0785205b64a 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -192,7 +192,10 @@ export { ComponentOptionsWithObjectProps as ComponentOptionsWithProps, ComponentOptionsWithArrayProps } from './componentOptions' -export { ComponentPublicInstance } from './componentProxy' +export { + ComponentPublicInstance, + ComponentCustomProperties +} from './componentProxy' export { Renderer, RendererNode, diff --git a/test-dts/componentCustomProperties.test-d.ts b/test-dts/componentCustomProperties.test-d.ts new file mode 100644 index 00000000000..60267c6b4c2 --- /dev/null +++ b/test-dts/componentCustomProperties.test-d.ts @@ -0,0 +1,20 @@ +import { expectError } from 'tsd' +import { defineComponent } from './index' + +declare module '@vue/runtime-core' { + interface ComponentCustomProperties { + state: 'stopped' | 'running' + } +} + +export const Custom = defineComponent({ + data: () => ({ counter: 0 }), + methods: { + aMethod() { + expectError(this.notExisting) + this.counter++ + this.state = 'running' + expectError((this.state = 'not valid')) + } + } +}) From 7c868ed3669178aa780b64f782051faaca0943b8 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Fri, 17 Apr 2020 10:26:12 +0200 Subject: [PATCH 2/5] typo --- packages/runtime-core/src/componentProxy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index 917bcebc89c..2ef7cca4b3f 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -46,7 +46,7 @@ import { warn } from './warning' * app.config.globalProperties.$router = router * * const vm = app.mount('#app') - * // we cann access the router from the instance + * // we can access the router from the instance * vm.$router.push('/') * ``` */ From 5cdc19160bca55f3a0d554e4d7784f5245e7f4c1 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Fri, 17 Apr 2020 10:53:57 +0200 Subject: [PATCH 3/5] test: fix failing test --- packages/runtime-core/src/apiWatch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index 967c77f8f97..c0df9dc3b6e 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -276,7 +276,7 @@ export function instanceWatch( cb: Function, options?: WatchOptions ): StopHandle { - const ctx = this.proxy as Data + const ctx = (this.proxy as unknown) as Data const getter = isString(source) ? () => ctx[source] : source.bind(ctx) const stop = watch(getter, cb.bind(ctx), options) onBeforeUnmount(stop, this) From f6517dbf93ef9b25f20fc449ade467b2f1b567ab Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 17 Apr 2020 09:01:36 -0400 Subject: [PATCH 4/5] Update componentProxy.ts --- packages/runtime-core/src/componentProxy.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index 2ef7cca4b3f..183207e90ab 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -24,7 +24,6 @@ import { } from './componentRenderUtils' import { warn } from './warning' -// /** * Custom properties added to component instances in any way and can be accessed through `this` * From 63e792561814372635683b0cfa63fa4f452683f5 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 17 Apr 2020 09:07:17 -0400 Subject: [PATCH 5/5] chore: fix tests --- packages/runtime-core/src/apiWatch.ts | 9 +++++---- packages/runtime-core/src/componentOptions.ts | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index c0df9dc3b6e..ff3e7c6257e 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -20,7 +20,6 @@ import { import { currentInstance, ComponentInternalInstance, - Data, isInSSRComponentSetup, recordInstanceBoundEffect } from './component' @@ -276,9 +275,11 @@ export function instanceWatch( cb: Function, options?: WatchOptions ): StopHandle { - const ctx = (this.proxy as unknown) as Data - const getter = isString(source) ? () => ctx[source] : source.bind(ctx) - const stop = watch(getter, cb.bind(ctx), options) + const publicThis = this.proxy as any + const getter = isString(source) + ? () => publicThis[source] + : source.bind(publicThis) + const stop = watch(getter, cb.bind(publicThis), options) onBeforeUnmount(stop, this) return stop } diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index e8fbfad4ab3..39087e8c311 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -528,7 +528,7 @@ function createWatcher( publicThis: ComponentPublicInstance, key: string ) { - const getter = () => (publicThis as Data)[key] + const getter = () => (publicThis as any)[key] if (isString(raw)) { const handler = ctx[raw] if (isFunction(handler)) {