diff --git a/packages/runtime-core/__tests__/componentProxy.spec.ts b/packages/runtime-core/__tests__/componentProxy.spec.ts index f37bfe3d9..4a4b56a84 100644 --- a/packages/runtime-core/__tests__/componentProxy.spec.ts +++ b/packages/runtime-core/__tests__/componentProxy.spec.ts @@ -69,7 +69,7 @@ describe('component: proxy', () => { expect('count' in instanceProxy).toBe(false) }) - test('public properties', () => { + test('public properties', async () => { let instance: ComponentInternalInstance let instanceProxy: any const Comp = { @@ -96,6 +96,11 @@ describe('component: proxy', () => { expect(instanceProxy.$options).toBe(instance!.type) expect(() => (instanceProxy.$data = {})).toThrow(TypeError) expect(`Attempting to mutate public property "$data"`).toHaveBeenWarned() + + const nextTickThis = await instanceProxy.$nextTick(function(this: any) { + return this + }) + expect(nextTickThis).toBe(instanceProxy) }) test('user attached properties', async () => { diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index e0e239a79..e45fd7755 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -213,7 +213,7 @@ const publicPropertiesMap: PublicPropertiesMap = extend(Object.create(null), { $emit: i => i.emit, $options: i => (__FEATURE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type), $forceUpdate: i => () => queueJob(i.update), - $nextTick: () => nextTick, + $nextTick: i => nextTick.bind(i.proxy!), $watch: i => (__FEATURE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP) } as PublicPropertiesMap) diff --git a/packages/runtime-core/src/scheduler.ts b/packages/runtime-core/src/scheduler.ts index 9c90f5c53..32fce93cc 100644 --- a/packages/runtime-core/src/scheduler.ts +++ b/packages/runtime-core/src/scheduler.ts @@ -1,5 +1,6 @@ import { ErrorCodes, callWithErrorHandling } from './errorHandling' import { isArray } from '@vue/shared' +import { ComponentPublicInstance } from './componentPublicInstance' export interface SchedulerJob { (): void @@ -48,9 +49,12 @@ let currentPreFlushParentJob: SchedulerJob | null = null const RECURSION_LIMIT = 100 type CountMap = Map -export function nextTick(fn?: () => void): Promise { +export function nextTick( + this: ComponentPublicInstance | void, + fn?: () => void +): Promise { const p = currentFlushPromise || resolvedPromise - return fn ? p.then(fn) : p + return fn ? p.then(this ? fn.bind(this) : fn) : p } export function queueJob(job: SchedulerJob) {