diff --git a/src/core/vdom/create-component.js b/src/core/vdom/create-component.js index 8957822470b..4062debdd25 100644 --- a/src/core/vdom/create-component.js +++ b/src/core/vdom/create-component.js @@ -238,8 +238,21 @@ function installComponentHooks (data: VNodeData) { const hooks = data.hook || (data.hook = {}) for (let i = 0; i < hooksToMerge.length; i++) { const key = hooksToMerge[i] - hooks[key] = componentVNodeHooks[key] + const existing = hooks[key] + const toMerge = componentVNodeHooks[key] + if (existing !== toMerge && !(existing && existing._merged)) { + hooks[key] = existing ? mergeHook(toMerge, existing) : toMerge + } + } +} + +function mergeHook (f1, f2) { + const merged = (a, b, c, d) => { + f1(a, b, c, d) + f2(a, b, c, d) } + merged._merged = true + return merged } // transform component v-model info (value and callback) into diff --git a/test/unit/modules/vdom/patch/edge-cases.spec.js b/test/unit/modules/vdom/patch/edge-cases.spec.js index 7555833c289..4c5702b47bf 100644 --- a/test/unit/modules/vdom/patch/edge-cases.spec.js +++ b/test/unit/modules/vdom/patch/edge-cases.spec.js @@ -393,9 +393,15 @@ describe('vdom patch: edge cases', () => { extends: Base } + // sometimes we do need to tap into these internal hooks (e.g. in vue-router) + // so make sure it does work + const inlineHookSpy = jasmine.createSpy('inlineInit') + const vm = new Vue({ render (h) { - const data = { staticClass: 'text-red' } + const data = { staticClass: 'text-red', hook: { + init: inlineHookSpy + }} return h('div', [ h(Foo, data), @@ -405,5 +411,6 @@ describe('vdom patch: edge cases', () => { }).$mount() expect(vm.$el.textContent).toBe('FooBar') + expect(inlineHookSpy.calls.count()).toBe(2) }) })