import {
currentInstance,
ComponentInternalInstance,
- Data,
isInSSRComponentSetup,
recordInstanceBoundEffect
} from './component'
cb: Function,
options?: WatchOptions
): StopHandle {
- const ctx = this.proxy 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
}
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)) {
} 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 can 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<
UnwrapRef<B> &
D &
ExtractComputedReturns<C> &
- M
+ M &
+ ComponentCustomProperties
const publicPropertiesMap: Record<
string,
ComponentOptionsWithObjectProps as ComponentOptionsWithProps,
ComponentOptionsWithArrayProps
} from './componentOptions'
-export { ComponentPublicInstance } from './componentProxy'
+export {
+ ComponentPublicInstance,
+ ComponentCustomProperties
+} from './componentProxy'
export {
Renderer,
RendererNode,
--- /dev/null
+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'))
+ }
+ }
+})