diff --git a/src/core/util/options.js b/src/core/util/options.js index fc7826dc01d..333d08ab755 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -376,13 +376,13 @@ export function mergeOptions ( } if (typeof child === 'function') { - child = child.options + child = child.extendOptions } normalizeProps(child, vm) normalizeInject(child, vm) normalizeDirectives(child) - + // Apply extends and mixins on the child options, // but only if it is a raw options object that isn't // the result of another mergeOptions call. diff --git a/test/unit/features/options/mixins.spec.js b/test/unit/features/options/mixins.spec.js index 8385edfe03c..65c4e6055ff 100644 --- a/test/unit/features/options/mixins.spec.js +++ b/test/unit/features/options/mixins.spec.js @@ -109,4 +109,32 @@ describe('Options mixins', () => { expect(vm.b).toBeDefined() expect(vm.$options.directives.c).toBeDefined() }) + + it('should not mix global mixined lifecycle hook twice', () => { + const spy = jasmine.createSpy('global mixed in lifecycle hook') + Vue.mixin({ + created() { + spy() + } + }) + + const mixin1 = Vue.extend({ + methods: { + a() {} + } + }) + + const mixin2 = Vue.extend({ + mixins: [mixin1], + }) + + const Child = Vue.extend({ + mixins: [mixin2], + }) + + const vm = new Child() + + expect(typeof vm.$options.methods.a).toBe('function') + expect(spy.calls.count()).toBe(1) + }) })