diff --git a/src/core/util/options.js b/src/core/util/options.js index 53f968301..4335b3559 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -172,7 +172,7 @@ strats.watch = function (parentVal: ?Object, childVal: ?Object): ?Object { } ret[key] = parent ? parent.concat(child) - : [child] + : Array.isArray(child) ? child : [child] } return ret } diff --git a/test/unit/features/options/extends.spec.js b/test/unit/features/options/extends.spec.js index fd02fce43..d50b30189 100644 --- a/test/unit/features/options/extends.spec.js +++ b/test/unit/features/options/extends.spec.js @@ -47,3 +47,44 @@ describe('Options extends', () => { expect(vm.c).toBe(3) }) }) + +describe('Options extends with Object.prototype.watch', () => { + beforeAll(function () { + if (!Object.prototype.watch) { + // eslint-disable-next-line no-extend-native + Object.prototype.watch = { + remove: true + } + } + }) + afterAll(function () { + if (Object.prototype.watch && Object.prototype.watch.remove) { + delete Object.prototype.watch + } + }) + it('should work with global mixins', done => { + Vue.use({ + install: function () { + Vue.mixin({}) + } + }) + const spy = jasmine.createSpy('watch') + const A = Vue.extend({ + data: function () { + return { a: 1 } + }, + watch: { + a: spy + }, + created: function () { + this.a = 2 + } + }) + new Vue({ + extends: A + }) + waitForUpdate(() => { + expect(spy).toHaveBeenCalledWith(2, 1) + }).then(done) + }) +}) diff --git a/test/unit/features/options/watch.spec.js b/test/unit/features/options/watch.spec.js index 702cd2b8c..071d1ad83 100644 --- a/test/unit/features/options/watch.spec.js +++ b/test/unit/features/options/watch.spec.js @@ -104,4 +104,43 @@ describe('Options watch', () => { expect(spy).toHaveBeenCalledWith(vm.a, oldA) }).then(done) }) + + it('correctly merges multiple extends', done => { + var spy2 = jasmine.createSpy('A') + var spy3 = jasmine.createSpy('B') + var A = Vue.extend({ + data: function () { + return { + a: 0, + b: 0 + } + }, + watch: { + b: spy + } + }) + + var B = Vue.extend({ + extends: A, + watch: { + a: spy2 + } + }) + + var C = Vue.extend({ + extends: B, + watch: { + a: spy3 + } + }) + + var vm = new C() + vm.a = 1 + + waitForUpdate(() => { + expect(spy).not.toHaveBeenCalled() + expect(spy2).toHaveBeenCalledWith(1, 0) + expect(spy3).toHaveBeenCalledWith(1, 0) + }).then(done) + }) })