diff --git a/src/core/instance/render.js b/src/core/instance/render.js index 48f990b5c8e..85601ba4caf 100644 --- a/src/core/instance/render.js +++ b/src/core/instance/render.js @@ -26,7 +26,7 @@ export function initRender (vm: Component) { export function renderMixin (Vue: Class) { Vue.prototype.$nextTick = function (fn: Function) { - nextTick(fn, this) + return nextTick(fn, this) } Vue.prototype._render = function (): VNode { diff --git a/src/core/util/env.js b/src/core/util/env.js index 9f974b2fa41..dd7135465cb 100644 --- a/src/core/util/env.js +++ b/src/core/util/env.js @@ -87,13 +87,17 @@ export const nextTick = (function () { } return function queueNextTick (cb: Function, ctx?: Object) { - const func = ctx - ? function () { cb.call(ctx) } - : cb - callbacks.push(func) - if (!pending) { - pending = true - timerFunc() + if (cb) { + var func = ctx + ? function () { cb.call(ctx) } + : cb + callbacks.push(func) + if (!pending) { + pending = true + timerFunc() + } + } else if (typeof Promise !== 'undefined') { + return Promise.resolve(ctx) } } })() diff --git a/test/unit/features/instance/methods-lifecycle.spec.js b/test/unit/features/instance/methods-lifecycle.spec.js index 07a687fbf51..865d67ace22 100644 --- a/test/unit/features/instance/methods-lifecycle.spec.js +++ b/test/unit/features/instance/methods-lifecycle.spec.js @@ -109,5 +109,22 @@ describe('Instance methods lifecycle', () => { done() }) }) + + if (typeof Promise !== 'undefined') { + it('should be called after DOM update in correct context, when using Promise syntax', done => { + const vm = new Vue({ + template: '
{{ msg }}
', + data: { + msg: 'foo' + } + }).$mount() + vm.msg = 'bar' + vm.$nextTick().then(function (ctx) { + expect(ctx).toBe(vm) + expect(vm.$el.textContent).toBe('bar') + done() + }) + }) + } }) }) diff --git a/test/unit/modules/util/next-tick.spec.js b/test/unit/modules/util/next-tick.spec.js new file mode 100644 index 00000000000..fc78931b020 --- /dev/null +++ b/test/unit/modules/util/next-tick.spec.js @@ -0,0 +1,25 @@ +import { nextTick } from 'core/util/env' + +describe('nextTick', () => { + it('accepts a callback', done => { + nextTick(done) + }) + + it('returns undefined when passed a callback', () => { + expect(typeof nextTick(() => {})).toBe('undefined') + }) + + if (typeof Promise !== 'undefined') { + it('returns a Promise when provided no callback', done => { + nextTick().then(done) + }) + + it('returns a Promise with a context argument when provided a falsy callback and an object', done => { + const obj = {} + nextTick(undefined, obj).then(ctx => { + expect(ctx).toBe(obj) + done() + }) + }) + } +})