]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): ensure consistent $options merge behavior with 2.x (#1986)
authorᴜɴвʏтᴇ <i@shangyes.net>
Tue, 1 Sep 2020 01:04:06 +0000 (20:04 -0500)
committerGitHub <noreply@github.com>
Tue, 1 Sep 2020 01:04:06 +0000 (21:04 -0400)
close #1978 , close #1979

packages/runtime-core/__tests__/apiCreateApp.spec.ts
packages/runtime-core/__tests__/apiOptions.spec.ts
packages/runtime-core/src/componentOptions.ts

index c3be3476c2c09bbd08ac2c67eb3e7c2ce1a95bda..0c7faf711aa12dcf8539beb1a6048bffa1f786ab 100644 (file)
@@ -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', () => {
index e3151fbfa420783139dc02a7e292bfc162323fd4..4504649bc5e8ecc4471e7426d7d86e7cd18a4e3d 100644 (file)
@@ -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() {
index 29a09bf1b424b7942a888c7ce84897dc6bcead5b..ae7e80a40c2c1b0850f9f37908302757962a8a57 100644 (file)
@@ -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))
 }