parent
71f7c25fbe
commit
5bce2ae723
@ -20,7 +20,9 @@ import {
|
|||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
createTextVNode,
|
createTextVNode,
|
||||||
SetupContext,
|
SetupContext,
|
||||||
createApp
|
createApp,
|
||||||
|
FunctionalComponent,
|
||||||
|
renderList
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
import { PatchFlags, SlotFlags } from '@vue/shared'
|
import { PatchFlags, SlotFlags } from '@vue/shared'
|
||||||
import { SuspenseImpl } from '../src/components/Suspense'
|
import { SuspenseImpl } from '../src/components/Suspense'
|
||||||
@ -821,4 +823,62 @@ describe('renderer: optimized mode', () => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
expect(inner(root)).toBe('<div><div>true</div></div>')
|
expect(inner(root)).toBe('<div><div>true</div></div>')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #3881
|
||||||
|
// root cause: fragment inside a compiled slot passed to component which
|
||||||
|
// programmatically invokes the slot. The entire slot should de-opt but
|
||||||
|
// the fragment was incorretly put in optimized mode which causes it to skip
|
||||||
|
// updates for its inner components.
|
||||||
|
test('fragments inside programmatically invoked compiled slot should de-opt properly', async () => {
|
||||||
|
const Parent: FunctionalComponent = (_, { slots }) => slots.default!()
|
||||||
|
const Dummy = () => 'dummy'
|
||||||
|
|
||||||
|
const toggle = ref(true)
|
||||||
|
const force = ref(0)
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
render() {
|
||||||
|
if (!toggle.value) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return h(
|
||||||
|
Parent,
|
||||||
|
{ n: force.value },
|
||||||
|
{
|
||||||
|
default: withCtx(
|
||||||
|
() => [
|
||||||
|
createVNode('ul', null, [
|
||||||
|
(openBlock(),
|
||||||
|
createBlock(
|
||||||
|
Fragment,
|
||||||
|
null,
|
||||||
|
renderList(1, item => {
|
||||||
|
return createVNode('li', null, [createVNode(Dummy)])
|
||||||
|
}),
|
||||||
|
64 /* STABLE_FRAGMENT */
|
||||||
|
))
|
||||||
|
])
|
||||||
|
],
|
||||||
|
undefined,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
_: 1 /* STABLE */
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.mount(root)
|
||||||
|
|
||||||
|
// force a patch
|
||||||
|
force.value++
|
||||||
|
await nextTick()
|
||||||
|
expect(inner(root)).toBe(`<ul><li>dummy</li></ul>`)
|
||||||
|
|
||||||
|
// unmount
|
||||||
|
toggle.value = false
|
||||||
|
await nextTick()
|
||||||
|
// should successfully unmount without error
|
||||||
|
expect(inner(root)).toBe(`<!---->`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1170,7 +1170,7 @@ function baseCreateRenderer(
|
|||||||
const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''))!
|
const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''))!
|
||||||
|
|
||||||
let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2
|
let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2
|
||||||
if (patchFlag > 0) {
|
if (dynamicChildren) {
|
||||||
optimized = true
|
optimized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user