Skip to content

Commit

Permalink
fix(runtime-core): properly call lifecycle hooks in chained mixins & …
Browse files Browse the repository at this point in the history
…extends (#1974)

fix #1973
  • Loading branch information
HcySunYang authored Aug 26, 2020
1 parent 9153fc2 commit 6df0e73
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 4 deletions.
65 changes: 65 additions & 0 deletions packages/runtime-core/__tests__/apiOptions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
26 changes: 22 additions & 4 deletions packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
Expand Down

0 comments on commit 6df0e73

Please sign in to comment.