diff --git a/packages/runtime-core/__tests__/apiCreateApp.spec.ts b/packages/runtime-core/__tests__/apiCreateApp.spec.ts index c3be3476..0c7faf71 100644 --- a/packages/runtime-core/__tests__/apiCreateApp.spec.ts +++ b/packages/runtime-core/__tests__/apiCreateApp.spec.ts @@ -457,7 +457,7 @@ describe('api: createApp', () => { app.config.optionMergeStrategies.foo = (a, b) => (a ? `${a},` : ``) + b app.mount(nodeOps.createElement('div')) - expect(merged!).toBe('global,extends,mixin,local') + expect(merged!).toBe('local,extends,mixin,global') }) test('config.globalProperties', () => { diff --git a/packages/runtime-core/__tests__/apiOptions.spec.ts b/packages/runtime-core/__tests__/apiOptions.spec.ts index e3151fbf..4504649b 100644 --- a/packages/runtime-core/__tests__/apiOptions.spec.ts +++ b/packages/runtime-core/__tests__/apiOptions.spec.ts @@ -698,6 +698,50 @@ describe('api: options', () => { ]) }) + test('flatten merged options', async () => { + const MixinBase = { + msg1: 'base' + } + const ExtendsBase = { + msg2: 'base' + } + const Mixin = { + mixins: [MixinBase] + } + const Extends = { + extends: ExtendsBase + } + const Comp = defineComponent({ + extends: defineComponent(Extends), + mixins: [defineComponent(Mixin)], + render() { + return `${this.$options.msg1},${this.$options.msg2}` + } + }) + + expect(renderToString(h(Comp))).toBe('base,base') + }) + + test('options defined in component have higher priority', async () => { + const Mixin = { + msg1: 'base' + } + const Extends = { + msg2: 'base' + } + const Comp = defineComponent({ + msg1: 'local', + msg2: 'local', + extends: defineComponent(Extends), + mixins: [defineComponent(Mixin)], + render() { + return `${this.$options.msg1},${this.$options.msg2}` + } + }) + + expect(renderToString(h(Comp))).toBe('local,local') + }) + test('accessing setup() state from options', async () => { const Comp = defineComponent({ setup() { diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 29a09bf1..ae7e80a4 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -767,10 +767,8 @@ export function resolveMergedOptions( const globalMixins = instance.appContext.mixins if (!globalMixins.length && !mixins && !extendsOptions) return raw const options = {} - globalMixins.forEach(m => mergeOptions(options, m, instance)) - extendsOptions && mergeOptions(options, extendsOptions, instance) - mixins && mixins.forEach(m => mergeOptions(options, m, instance)) mergeOptions(options, raw, instance) + globalMixins.forEach(m => mergeOptions(options, m, instance)) return (raw.__merged = options) } @@ -783,4 +781,9 @@ function mergeOptions(to: any, from: any, instance: ComponentInternalInstance) { to[key] = from[key] } } + const { mixins, extends: extendsOptions } = from + + extendsOptions && mergeOptions(to, extendsOptions, instance) + mixins && + mixins.forEach((m: ComponentOptionsMixin) => mergeOptions(to, m, instance)) }