diff --git a/packages/runtime-core/__tests__/hmr.spec.ts b/packages/runtime-core/__tests__/hmr.spec.ts index 4b501052ce4..3691858feb6 100644 --- a/packages/runtime-core/__tests__/hmr.spec.ts +++ b/packages/runtime-core/__tests__/hmr.spec.ts @@ -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 @@ -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( + `
1

2

3

` + ) + } + createRecord(appId, App) + + render(h(App), root) + expect(serializeInner(root)).toBe( + `
1
1

2

3

` + ) + + // move the

3

into the
1
+ rerender( + appId, + compileToFunction( + `
1

3

2

` + ) + ) + expect(serializeInner(root)).toBe( + `
1

3

1

3

2

` + ) + }) }) diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index 7d873f5a125..7f04b90b11e 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -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' @@ -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,