mirror of https://github.com/vuejs/vue.git
fix: fix regression on duplicate component init when using shared data objects
fix #7805
This commit is contained in:
parent
cf0b1b745f
commit
984927a1a9
|
@ -32,7 +32,7 @@ import {
|
|||
renderRecyclableComponentTemplate
|
||||
} from 'weex/runtime/recycle-list/render-component-template'
|
||||
|
||||
// hooks to be invoked on component VNodes during patch
|
||||
// inline hooks to be invoked on component VNodes during patch
|
||||
const componentVNodeHooks = {
|
||||
init (
|
||||
vnode: VNodeWithData,
|
||||
|
@ -189,8 +189,8 @@ export function createComponent (
|
|||
}
|
||||
}
|
||||
|
||||
// merge component management hooks onto the placeholder node
|
||||
mergeHooks(data)
|
||||
// install component management hooks onto the placeholder node
|
||||
installComponentHooks(data)
|
||||
|
||||
// return a placeholder vnode
|
||||
const name = Ctor.options.name || tag
|
||||
|
@ -234,22 +234,11 @@ export function createComponentInstanceForVnode (
|
|||
return new vnode.componentOptions.Ctor(options)
|
||||
}
|
||||
|
||||
function mergeHooks (data: VNodeData) {
|
||||
if (!data.hook) {
|
||||
data.hook = {}
|
||||
}
|
||||
function installComponentHooks (data: VNodeData) {
|
||||
const hooks = data.hook || (data.hook = {})
|
||||
for (let i = 0; i < hooksToMerge.length; i++) {
|
||||
const key = hooksToMerge[i]
|
||||
const fromParent = data.hook[key]
|
||||
const ours = componentVNodeHooks[key]
|
||||
data.hook[key] = fromParent ? mergeHook(ours, fromParent) : ours
|
||||
}
|
||||
}
|
||||
|
||||
function mergeHook (one: Function, two: Function): Function {
|
||||
return function (a, b, c, d) {
|
||||
one(a, b, c, d)
|
||||
two(a, b, c, d)
|
||||
hooks[key] = componentVNodeHooks[key]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,10 @@ describe('create-component', () => {
|
|||
props: ['msg'],
|
||||
render () {}
|
||||
}
|
||||
const init = jasmine.createSpy()
|
||||
const data = {
|
||||
props: { msg: 'hello world' },
|
||||
attrs: { id: 1 },
|
||||
staticAttrs: { class: 'foo' },
|
||||
hook: { init },
|
||||
on: { notify: 'onNotify' }
|
||||
}
|
||||
const vnode = createComponent(child, data, vm, vm)
|
||||
|
@ -38,9 +36,6 @@ describe('create-component', () => {
|
|||
expect(vnode.elm).toBeUndefined()
|
||||
expect(vnode.ns).toBeUndefined()
|
||||
expect(vnode.context).toEqual(vm)
|
||||
|
||||
vnode.data.hook.init(vnode)
|
||||
expect(init.calls.argsFor(0)[0]).toBe(vnode)
|
||||
})
|
||||
|
||||
it('create a component when resolved with async loading', done => {
|
||||
|
|
|
@ -374,4 +374,36 @@ describe('vdom patch: edge cases', () => {
|
|||
expect(vm.$el.querySelector('custom-foo').getAttribute('selected')).toBe('1')
|
||||
Vue.config.ignoredElements = []
|
||||
})
|
||||
|
||||
// #7805
|
||||
it('should not cause duplicate init when components share data object', () => {
|
||||
const Base = {
|
||||
render (h) {
|
||||
return h('div', this.$options.name)
|
||||
}
|
||||
}
|
||||
|
||||
const Foo = {
|
||||
name: 'Foo',
|
||||
extends: Base
|
||||
}
|
||||
|
||||
const Bar = {
|
||||
name: 'Bar',
|
||||
extends: Base
|
||||
}
|
||||
|
||||
const vm = new Vue({
|
||||
render (h) {
|
||||
const data = { staticClass: 'text-red' }
|
||||
|
||||
return h('div', [
|
||||
h(Foo, data),
|
||||
h(Bar, data)
|
||||
])
|
||||
}
|
||||
}).$mount()
|
||||
|
||||
expect(vm.$el.textContent).toBe('FooBar')
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue