fix(runtime-core): properly call lifecycle hooks in chained mixins & extends (#1974)

fix #1973
This commit is contained in:
HcySunYang 2020-08-26 22:31:23 +08:00 committed by GitHub
parent 9153fc2d8a
commit 6df0e738cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 4 deletions

View File

@ -633,6 +633,71 @@ describe('api: options', () => {
expect(calls).toEqual(['base', 'mixin', 'comp']) 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 () => { test('accessing setup() state from options', async () => {
const Comp = defineComponent({ const Comp = defineComponent({
setup() { setup() {

View File

@ -614,11 +614,11 @@ function callSyncHook(
globalMixins: ComponentOptions[] globalMixins: ComponentOptions[]
) { ) {
callHookFromMixins(name, globalMixins, ctx) callHookFromMixins(name, globalMixins, ctx)
const baseHook = options.extends && options.extends[name]
if (baseHook) { const { extends: base, mixins } = options
baseHook.call(ctx) if (base) {
callHookFromExtends(name, base, ctx)
} }
const mixins = options.mixins
if (mixins) { if (mixins) {
callHookFromMixins(name, mixins, ctx) 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( function callHookFromMixins(
name: 'beforeCreate' | 'created', name: 'beforeCreate' | 'created',
mixins: ComponentOptions[], mixins: ComponentOptions[],
ctx: ComponentPublicInstance ctx: ComponentPublicInstance
) { ) {
for (let i = 0; i < mixins.length; i++) { for (let i = 0; i < mixins.length; i++) {
const chainedMixins = mixins[i].mixins
if (chainedMixins) {
callHookFromMixins(name, chainedMixins, ctx)
}
const fn = mixins[i][name] const fn = mixins[i][name]
if (fn) { if (fn) {
fn.call(ctx) fn.call(ctx)