Skip to content

Commit

Permalink
fix(runtime-core): ensure this context for $nextTick callback
Browse files Browse the repository at this point in the history
fix #2282
  • Loading branch information
yyx990803 committed Oct 5, 2020
1 parent f411924 commit 5c3e8e9
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 4 deletions.
7 changes: 6 additions & 1 deletion packages/runtime-core/__tests__/componentProxy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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 () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime-core/src/componentPublicInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
8 changes: 6 additions & 2 deletions packages/runtime-core/src/scheduler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
import { isArray } from '@vue/shared'
import { ComponentPublicInstance } from './componentPublicInstance'

export interface SchedulerJob {
(): void
Expand Down Expand Up @@ -48,9 +49,12 @@ let currentPreFlushParentJob: SchedulerJob | null = null
const RECURSION_LIMIT = 100
type CountMap = Map<SchedulerJob | SchedulerCb, number>

export function nextTick(fn?: () => void): Promise<void> {
export function nextTick(
this: ComponentPublicInstance | void,
fn?: () => void
): Promise<void> {
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) {
Expand Down

0 comments on commit 5c3e8e9

Please sign in to comment.