From a59112f7f96ac371dff64e313656d6e96065e970 Mon Sep 17 00:00:00 2001 From: Kael Watts-Deuchar Date: Sun, 30 Sep 2018 22:24:31 +1000 Subject: [PATCH 1/3] fix(mergeOptions): skip mixins and extends if child is already merged fixes #8865 --- src/core/util/options.js | 4 ++-- test/unit/features/global-api/extend.spec.js | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/core/util/options.js b/src/core/util/options.js index 5f0d10d3361..7f0ad2cf788 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -379,10 +379,10 @@ export function mergeOptions ( normalizeInject(child, vm) normalizeDirectives(child) const extendsFrom = child.extends - if (extendsFrom) { + if (extendsFrom && !child._base) { parent = mergeOptions(parent, extendsFrom, vm) } - if (child.mixins) { + if (child.mixins && !child._base) { for (let i = 0, l = child.mixins.length; i < l; i++) { parent = mergeOptions(parent, child.mixins[i], vm) } diff --git a/test/unit/features/global-api/extend.spec.js b/test/unit/features/global-api/extend.spec.js index 4a4a73505b9..044156074a5 100644 --- a/test/unit/features/global-api/extend.spec.js +++ b/test/unit/features/global-api/extend.spec.js @@ -71,6 +71,25 @@ describe('Global API: extend', () => { expect(calls).toEqual([1, 2, 3]) }) + it('should not merge nested mixins', () => { + const A = Vue.extend({ + created: () => {} + }) + const B = Vue.extend({ + mixins: [A], + created: () => {} + }) + const C = Vue.extend({ + extends: B, + created: () => {} + }) + const D = Vue.extend({ + mixins: [C], + created: () => {} + }) + expect(D.options.created.length).toBe(4) + }) + it('should merge methods', () => { const A = Vue.extend({ methods: { From 30c5b30f382e1ec7570c0534fb9fe41f52e3a9a4 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Sat, 20 Oct 2018 20:49:28 +1100 Subject: [PATCH 2/3] update test name Co-Authored-By: KaelWD --- test/unit/features/global-api/extend.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/features/global-api/extend.spec.js b/test/unit/features/global-api/extend.spec.js index 044156074a5..f0867ac1b5a 100644 --- a/test/unit/features/global-api/extend.spec.js +++ b/test/unit/features/global-api/extend.spec.js @@ -71,7 +71,7 @@ describe('Global API: extend', () => { expect(calls).toEqual([1, 2, 3]) }) - it('should not merge nested mixins', () => { + it('should not merge nested mixins created with Vue.extend', () => { const A = Vue.extend({ created: () => {} }) From 70871837ed91d1be98a360cbf24cbf6182c459c7 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 30 Nov 2018 17:49:22 -0500 Subject: [PATCH 3/3] Update options.js --- src/core/util/options.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/core/util/options.js b/src/core/util/options.js index 7f0ad2cf788..2906ddd1910 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -378,15 +378,22 @@ export function mergeOptions ( normalizeProps(child, vm) normalizeInject(child, vm) normalizeDirectives(child) - const extendsFrom = child.extends - if (extendsFrom && !child._base) { - parent = mergeOptions(parent, extendsFrom, vm) - } - if (child.mixins && !child._base) { - for (let i = 0, l = child.mixins.length; i < l; i++) { - parent = mergeOptions(parent, child.mixins[i], vm) + + // 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. + // Only merged options has the _base property. + if (!child._base) { + if (child.extends) { + parent = mergeOptions(parent, child.extends, vm) + } + if (child.mixins) { + for (let i = 0, l = child.mixins.length; i < l; i++) { + parent = mergeOptions(parent, child.mixins[i], vm) + } } } + const options = {} let key for (key in parent) {