Skip to content

Commit

Permalink
fix(hmr): fix render error in change static nodes (vuejs#6978)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangzhonghe committed Nov 12, 2022
1 parent 6e8b6b3 commit 73dd0d1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
30 changes: 29 additions & 1 deletion packages/runtime-core/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const { createRecord, rerender, reload } = __VUE_HMR_RUNTIME__
registerRuntimeCompiler(compileToFunction)

function compileToFunction(template: string) {
const { code } = baseCompile(template)
const { code } = baseCompile(template, { hoistStatic: true })
const render = new Function('Vue', code)(
runtimeTest
) as InternalRenderFunction
Expand Down Expand Up @@ -536,4 +536,32 @@ describe('hot module replacement', () => {
render(h(Foo), root)
expect(serializeInner(root)).toBe('bar')
})

test('rerender in change hoisted nodes', () => {
const root = nodeOps.createElement('div')
const appId = 'test-app-id'
const App: ComponentOptions = {
__hmrId: appId,
render: compileToFunction(
`<div v-for="item of 2"><div>1</div></div><p>2</p><p>3</p>`
)
}
createRecord(appId, App)

render(h(App), root)
expect(serializeInner(root)).toBe(
`<div><div>1</div></div><div><div>1</div></div><p>2</p><p>3</p>`
)

// move the <p>3</p> into the <div>1</div>
rerender(
appId,
compileToFunction(
`<div v-for="item of 2"><div>1<p>3</p></div></div><p>2</p>`
)
)
expect(serializeInner(root)).toBe(
`<div><div>1<p>3</p></div></div><div><div>1<p>3</p></div></div><p>2</p>`
)
})
})
8 changes: 7 additions & 1 deletion packages/runtime-core/src/vnode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
} from './componentRenderContext'
import { RendererNode, RendererElement } from './renderer'
import { NULL_DYNAMIC_COMPONENT } from './helpers/resolveAssets'
import { hmrDirtyComponents } from './hmr'
import { hmrDirtyComponents, isHmrUpdating } from './hmr'
import { convertLegacyComponent } from './compat/component'
import { convertLegacyVModelProps } from './compat/componentVModel'
import { defineLegacyVNodeProperties } from './compat/renderFn'
Expand Down Expand Up @@ -423,6 +423,12 @@ function createBaseVNode(
isBlockNode = false,
needFullChildrenNormalization = false
) {
// #6978 the children maybe a hoisted array that should be cloned
// since it maybe changed during HMR
if (__DEV__ && isHmrUpdating && isArray(children)) {
children = [...children]
}

const vnode = {
__v_isVNode: true,
__v_skip: true,
Expand Down

0 comments on commit 73dd0d1

Please sign in to comment.