Просмотр исходного кода

fix(runtime-core): should call chained mixins and extends (#3040)

fix #3038
HcySunYang 5 лет назад
Родитель
Сommit
b58bb16959

+ 87 - 0
packages/runtime-core/__tests__/apiOptions.spec.ts

@@ -644,6 +644,93 @@ describe('api: options', () => {
     expect(renderToString(h(Comp))).toBe('from mixin')
   })
 
+  test('chained mixins in extends', () => {
+    const calls: string[] = []
+    const mixinA = {
+      beforeCreate() {
+        calls.push('mixinA beforeCreate')
+      },
+      created() {
+        calls.push('mixinA created')
+      }
+    }
+
+    const extendA = {
+      mixins: [mixinA],
+      beforeCreate() {
+        calls.push('extendA beforeCreate')
+      },
+      created() {
+        calls.push('extendA created')
+      }
+    }
+
+    const Comp = {
+      extends: extendA,
+      render: () => '123',
+      beforeCreate() {
+        calls.push('self beforeCreate')
+      },
+      created() {
+        calls.push('self created')
+      }
+    }
+
+    expect(renderToString(h(Comp))).toBe(`123`)
+    expect(calls).toEqual([
+      'mixinA beforeCreate',
+      'extendA beforeCreate',
+      'self beforeCreate',
+      'mixinA created',
+      'extendA created',
+      'self created'
+    ])
+  })
+
+  test('chained extends in mixins', () => {
+    const calls: string[] = []
+
+    const extendA = {
+      beforeCreate() {
+        calls.push('extendA beforeCreate')
+      },
+      created() {
+        calls.push('extendA created')
+      }
+    }
+
+    const mixinA = {
+      extends: extendA,
+      beforeCreate() {
+        calls.push('mixinA beforeCreate')
+      },
+      created() {
+        calls.push('mixinA created')
+      }
+    }
+
+    const Comp = {
+      mixins: [mixinA],
+      render: () => '123',
+      beforeCreate() {
+        calls.push('self beforeCreate')
+      },
+      created() {
+        calls.push('self created')
+      }
+    }
+
+    expect(renderToString(h(Comp))).toBe(`123`)
+    expect(calls).toEqual([
+      'extendA beforeCreate',
+      'mixinA beforeCreate',
+      'self beforeCreate',
+      'extendA created',
+      'mixinA created',
+      'self created'
+    ])
+  })
+
   test('extends', () => {
     const calls: string[] = []
     const Base = {

+ 8 - 0
packages/runtime-core/src/componentOptions.ts

@@ -839,6 +839,10 @@ function callHookFromExtends(
   if (base.extends) {
     callHookFromExtends(name, type, base.extends, instance)
   }
+  const chainedMixins = base.mixins
+  if (chainedMixins) {
+    callHookFromMixins(name, type, chainedMixins, instance)
+  }
   const baseHook = base[name]
   if (baseHook) {
     callWithAsyncErrorHandling(baseHook.bind(instance.proxy!), instance, type)
@@ -853,6 +857,10 @@ function callHookFromMixins(
 ) {
   for (let i = 0; i < mixins.length; i++) {
     const chainedMixins = mixins[i].mixins
+    const chainedExtends = mixins[i].extends
+    if (chainedExtends) {
+      callHookFromExtends(name, type, chainedExtends, instance)
+    }
     if (chainedMixins) {
       callHookFromMixins(name, type, chainedMixins, instance)
     }