This commit is contained in:
linzhe 2025-05-05 20:38:32 +00:00 committed by GitHub
commit f2b3ffa37e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 2 deletions

View File

@ -29,7 +29,7 @@ import {
setBlockTracking, setBlockTracking,
withCtx, withCtx,
} from '@vue/runtime-test' } from '@vue/runtime-test'
import { PatchFlags, SlotFlags } from '@vue/shared' import { PatchFlags, SlotFlags, toDisplayString } from '@vue/shared'
import { SuspenseImpl } from '../src/components/Suspense' import { SuspenseImpl } from '../src/components/Suspense'
describe('renderer: optimized mode', () => { describe('renderer: optimized mode', () => {
@ -1294,4 +1294,62 @@ describe('renderer: optimized mode', () => {
expect(inner(root)).toBe('<!--v-if-->') expect(inner(root)).toBe('<!--v-if-->')
expect(beforeUnmountSpy).toHaveBeenCalledTimes(1) expect(beforeUnmountSpy).toHaveBeenCalledTimes(1)
}) })
// #12411
test('handle patch stable fragment with non-reactive v-for source', async () => {
const count = ref(0)
const foo: any = []
function updateFoo() {
for (let n = 0; n < 3; n++) {
foo[n] = n + 1 + '_foo'
}
}
const Comp = {
setup() {
return () => {
// <div>{{ count }}</div>
// <div v-for='item in foo'>{{ item }}</div>
return (
openBlock(),
createElementBlock(
Fragment,
null,
[
createElementVNode(
'div',
null,
toDisplayString(count.value),
PatchFlags.TEXT,
),
(openBlock(),
createElementBlock(
Fragment,
null,
renderList(foo, item => {
return createElementVNode(
'div',
null,
toDisplayString(item),
PatchFlags.TEXT,
)
}),
PatchFlags.STABLE_FRAGMENT,
)),
],
PatchFlags.STABLE_FRAGMENT,
)
)
}
},
}
render(h(Comp), root)
expect(inner(root)).toBe('<div>0</div>')
updateFoo()
count.value++
await nextTick()
expect(inner(root)).toBe(
'<div>1</div><div>1_foo</div><div>2_foo</div><div>3_foo</div>',
)
})
}) })

View File

@ -1079,7 +1079,8 @@ function baseCreateRenderer(
dynamicChildren && dynamicChildren &&
// #2715 the previous fragment could've been a BAILed one as a result // #2715 the previous fragment could've been a BAILed one as a result
// of renderSlot() with no valid children // of renderSlot() with no valid children
n1.dynamicChildren n1.dynamicChildren &&
n1.dynamicChildren.length === dynamicChildren.length
) { ) {
// a stable fragment (template root or <template v-for>) doesn't need to // a stable fragment (template root or <template v-for>) doesn't need to
// patch children order, but it may contain dynamicChildren. // patch children order, but it may contain dynamicChildren.