fix(hmr): always force full child component props update in HMR mode
This commit is contained in:
parent
5b8883a846
commit
1b946c85df
@ -71,13 +71,13 @@ describe('hot module replacement', () => {
|
|||||||
expect(serializeInner(root)).toBe(`<div>11</div>`)
|
expect(serializeInner(root)).toBe(`<div>11</div>`)
|
||||||
|
|
||||||
// // Update text while preserving state
|
// // Update text while preserving state
|
||||||
// rerender(
|
rerender(
|
||||||
// parentId,
|
parentId,
|
||||||
// compileToFunction(
|
compileToFunction(
|
||||||
// `<div @click="count++">{{ count }}!<Child>{{ count }}</Child></div>`
|
`<div @click="count++">{{ count }}!<Child>{{ count }}</Child></div>`
|
||||||
// )
|
)
|
||||||
// )
|
)
|
||||||
// expect(serializeInner(root)).toBe(`<div>1!1</div>`)
|
expect(serializeInner(root)).toBe(`<div>1!1</div>`)
|
||||||
|
|
||||||
// Should force child update on slot content change
|
// Should force child update on slot content change
|
||||||
rerender(
|
rerender(
|
||||||
@ -147,4 +147,75 @@ describe('hot module replacement', () => {
|
|||||||
expect(unmountSpy).toHaveBeenCalledTimes(1)
|
expect(unmountSpy).toHaveBeenCalledTimes(1)
|
||||||
expect(mountSpy).toHaveBeenCalledTimes(1)
|
expect(mountSpy).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #1156 - static nodes should retain DOM element reference across updates
|
||||||
|
// when HMR is active
|
||||||
|
test('static el reference', async () => {
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
const id = 'test-static-el'
|
||||||
|
|
||||||
|
const template = `<div>
|
||||||
|
<div>{{ count }}</div>
|
||||||
|
<button @click="count++">++</button>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
const Comp: ComponentOptions = {
|
||||||
|
__hmrId: id,
|
||||||
|
data() {
|
||||||
|
return { count: 0 }
|
||||||
|
},
|
||||||
|
render: compileToFunction(template)
|
||||||
|
}
|
||||||
|
createRecord(id, Comp)
|
||||||
|
|
||||||
|
render(h(Comp), root)
|
||||||
|
expect(serializeInner(root)).toBe(
|
||||||
|
`<div><div>0</div><button>++</button></div>`
|
||||||
|
)
|
||||||
|
|
||||||
|
// 1. click to trigger update
|
||||||
|
triggerEvent((root as any).children[0].children[1], 'click')
|
||||||
|
await nextTick()
|
||||||
|
expect(serializeInner(root)).toBe(
|
||||||
|
`<div><div>1</div><button>++</button></div>`
|
||||||
|
)
|
||||||
|
|
||||||
|
// 2. trigger HMR
|
||||||
|
rerender(
|
||||||
|
id,
|
||||||
|
compileToFunction(template.replace(`<button`, `<button class="foo"`))
|
||||||
|
)
|
||||||
|
expect(serializeInner(root)).toBe(
|
||||||
|
`<div><div>1</div><button class="foo">++</button></div>`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// #1157 - component should force full props update when HMR is active
|
||||||
|
test('force update child component w/ static props', () => {
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
const parentId = 'test2-parent'
|
||||||
|
const childId = 'test2-child'
|
||||||
|
|
||||||
|
const Child: ComponentOptions = {
|
||||||
|
__hmrId: childId,
|
||||||
|
props: {
|
||||||
|
msg: String
|
||||||
|
},
|
||||||
|
render: compileToFunction(`<div>{{ msg }}</div>`)
|
||||||
|
}
|
||||||
|
createRecord(childId, Child)
|
||||||
|
|
||||||
|
const Parent: ComponentOptions = {
|
||||||
|
__hmrId: parentId,
|
||||||
|
components: { Child },
|
||||||
|
render: compileToFunction(`<Child msg="foo" />`)
|
||||||
|
}
|
||||||
|
createRecord(parentId, Parent)
|
||||||
|
|
||||||
|
render(h(Parent), root)
|
||||||
|
expect(serializeInner(root)).toBe(`<div>foo</div>`)
|
||||||
|
|
||||||
|
rerender(parentId, compileToFunction(`<Child msg="bar" />`))
|
||||||
|
expect(serializeInner(root)).toBe(`<div>bar</div>`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1270,6 +1270,9 @@ function baseCreateRenderer(
|
|||||||
nextVNode: VNode,
|
nextVNode: VNode,
|
||||||
optimized: boolean
|
optimized: boolean
|
||||||
) => {
|
) => {
|
||||||
|
if (__DEV__ && instance.type.__hmrId) {
|
||||||
|
optimized = false
|
||||||
|
}
|
||||||
nextVNode.component = instance
|
nextVNode.component = instance
|
||||||
const prevProps = instance.vnode.props
|
const prevProps = instance.vnode.props
|
||||||
instance.vnode = nextVNode
|
instance.vnode = nextVNode
|
||||||
|
Loading…
Reference in New Issue
Block a user