feat(types): feat(types): add ComponentCustomProperties interface (#982)

This commit is contained in:
Evan You 2020-04-17 09:12:50 -04:00
parent 4cf5e07608
commit be21cfb1db
5 changed files with 59 additions and 7 deletions

View File

@ -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 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
}

View File

@ -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)) {

View File

@ -24,6 +24,33 @@ 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 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<
@ -53,7 +80,8 @@ export type ComponentPublicInstance<
UnwrapRef<B> &
D &
ExtractComputedReturns<C> &
M
M &
ComponentCustomProperties
const publicPropertiesMap: Record<
string,

View File

@ -192,7 +192,10 @@ export {
ComponentOptionsWithObjectProps as ComponentOptionsWithProps,
ComponentOptionsWithArrayProps
} from './componentOptions'
export { ComponentPublicInstance } from './componentProxy'
export {
ComponentPublicInstance,
ComponentCustomProperties
} from './componentProxy'
export {
Renderer,
RendererNode,

View File

@ -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'))
}
}
})