From 6df0e738cb9ae6db0c0e9c3c70d81147521bfe7f Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Wed, 26 Aug 2020 22:31:23 +0800 Subject: [PATCH] fix(runtime-core): properly call lifecycle hooks in chained mixins & extends (#1974) fix #1973 --- .../runtime-core/__tests__/apiOptions.spec.ts | 65 +++++++++++++++++++ packages/runtime-core/src/componentOptions.ts | 26 ++++++-- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/__tests__/apiOptions.spec.ts b/packages/runtime-core/__tests__/apiOptions.spec.ts index d61d46be363..e3151fbfa42 100644 --- a/packages/runtime-core/__tests__/apiOptions.spec.ts +++ b/packages/runtime-core/__tests__/apiOptions.spec.ts @@ -633,6 +633,71 @@ describe('api: options', () => { expect(calls).toEqual(['base', 'mixin', 'comp']) }) + test('beforeCreate/created in extends and mixins', () => { + const calls: string[] = [] + const BaseA = { + beforeCreate() { + calls.push('beforeCreateA') + }, + created() { + calls.push('createdA') + } + } + const BaseB = { + extends: BaseA, + beforeCreate() { + calls.push('beforeCreateB') + }, + created() { + calls.push('createdB') + } + } + + const MixinA = { + beforeCreate() { + calls.push('beforeCreateC') + }, + created() { + calls.push('createdC') + } + } + const MixinB = { + mixins: [MixinA], + beforeCreate() { + calls.push('beforeCreateD') + }, + created() { + calls.push('createdD') + } + } + + const Comp = { + extends: BaseB, + mixins: [MixinB], + beforeCreate() { + calls.push('selfBeforeCreate') + }, + created() { + calls.push('selfCreated') + }, + render() {} + } + + renderToString(h(Comp)) + expect(calls).toEqual([ + 'beforeCreateA', + 'beforeCreateB', + 'beforeCreateC', + 'beforeCreateD', + 'selfBeforeCreate', + 'createdA', + 'createdB', + 'createdC', + 'createdD', + 'selfCreated' + ]) + }) + 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 ff3927004ed..facca201d9e 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -614,11 +614,11 @@ function callSyncHook( globalMixins: ComponentOptions[] ) { callHookFromMixins(name, globalMixins, ctx) - const baseHook = options.extends && options.extends[name] - if (baseHook) { - baseHook.call(ctx) + + const { extends: base, mixins } = options + if (base) { + callHookFromExtends(name, base, ctx) } - const mixins = options.mixins if (mixins) { callHookFromMixins(name, mixins, ctx) } @@ -628,12 +628,30 @@ function callSyncHook( } } +function callHookFromExtends( + name: 'beforeCreate' | 'created', + base: ComponentOptions, + ctx: ComponentPublicInstance +) { + if (base.extends) { + callHookFromExtends(name, base.extends, ctx) + } + const baseHook = base[name] + if (baseHook) { + baseHook.call(ctx) + } +} + function callHookFromMixins( name: 'beforeCreate' | 'created', mixins: ComponentOptions[], ctx: ComponentPublicInstance ) { for (let i = 0; i < mixins.length; i++) { + const chainedMixins = mixins[i].mixins + if (chainedMixins) { + callHookFromMixins(name, chainedMixins, ctx) + } const fn = mixins[i][name] if (fn) { fn.call(ctx)