Skip to content

Commit

Permalink
feat(types): feat(types): add ComponentCustomProperties interface (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Apr 17, 2020
1 parent 4cf5e07 commit be21cfb
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 7 deletions.
9 changes: 5 additions & 4 deletions packages/runtime-core/src/apiWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
import {
currentInstance,
ComponentInternalInstance,
Data,
isInSSRComponentSetup,
recordInstanceBoundEffect
} from './component'
Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
30 changes: 29 additions & 1 deletion packages/runtime-core/src/componentProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down Expand Up @@ -53,7 +80,8 @@ export type ComponentPublicInstance<
UnwrapRef<B> &
D &
ExtractComputedReturns<C> &
M
M &
ComponentCustomProperties

const publicPropertiesMap: Record<
string,
Expand Down
5 changes: 4 additions & 1 deletion packages/runtime-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ export {
ComponentOptionsWithObjectProps as ComponentOptionsWithProps,
ComponentOptionsWithArrayProps
} from './componentOptions'
export { ComponentPublicInstance } from './componentProxy'
export {
ComponentPublicInstance,
ComponentCustomProperties
} from './componentProxy'
export {
Renderer,
RendererNode,
Expand Down
20 changes: 20 additions & 0 deletions test-dts/componentCustomProperties.test-d.ts
Original file line number Diff line number Diff line change
@@ -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'))
}
}
})

0 comments on commit be21cfb

Please sign in to comment.