Skip to content

Commit 5c3e8e9

Browse files
committed
fix(runtime-core): ensure this context for $nextTick callback
fix #2282
1 parent f411924 commit 5c3e8e9

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

packages/runtime-core/__tests__/componentProxy.spec.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe('component: proxy', () => {
6969
expect('count' in instanceProxy).toBe(false)
7070
})
7171

72-
test('public properties', () => {
72+
test('public properties', async () => {
7373
let instance: ComponentInternalInstance
7474
let instanceProxy: any
7575
const Comp = {
@@ -96,6 +96,11 @@ describe('component: proxy', () => {
9696
expect(instanceProxy.$options).toBe(instance!.type)
9797
expect(() => (instanceProxy.$data = {})).toThrow(TypeError)
9898
expect(`Attempting to mutate public property "$data"`).toHaveBeenWarned()
99+
100+
const nextTickThis = await instanceProxy.$nextTick(function(this: any) {
101+
return this
102+
})
103+
expect(nextTickThis).toBe(instanceProxy)
99104
})
100105

101106
test('user attached properties', async () => {

packages/runtime-core/src/componentPublicInstance.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ const publicPropertiesMap: PublicPropertiesMap = extend(Object.create(null), {
213213
$emit: i => i.emit,
214214
$options: i => (__FEATURE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
215215
$forceUpdate: i => () => queueJob(i.update),
216-
$nextTick: () => nextTick,
216+
$nextTick: i => nextTick.bind(i.proxy!),
217217
$watch: i => (__FEATURE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP)
218218
} as PublicPropertiesMap)
219219

packages/runtime-core/src/scheduler.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
22
import { isArray } from '@vue/shared'
3+
import { ComponentPublicInstance } from './componentPublicInstance'
34

45
export interface SchedulerJob {
56
(): void
@@ -48,9 +49,12 @@ let currentPreFlushParentJob: SchedulerJob | null = null
4849
const RECURSION_LIMIT = 100
4950
type CountMap = Map<SchedulerJob | SchedulerCb, number>
5051

51-
export function nextTick(fn?: () => void): Promise<void> {
52+
export function nextTick(
53+
this: ComponentPublicInstance | void,
54+
fn?: () => void
55+
): Promise<void> {
5256
const p = currentFlushPromise || resolvedPromise
53-
return fn ? p.then(fn) : p
57+
return fn ? p.then(this ? fn.bind(this) : fn) : p
5458
}
5559

5660
export function queueJob(job: SchedulerJob) {

0 commit comments

Comments
 (0)