Skip to content

Commit

Permalink
fix(runtime-core): avoid tracking slot fallback node as block
Browse files Browse the repository at this point in the history
test: add test case

chore: improve code

chore: update test

chore: update test
  • Loading branch information
edison1105 committed Sep 29, 2023
1 parent b775b71 commit ba26e1b
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 7 deletions.
79 changes: 78 additions & 1 deletion packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import {
createApp,
FunctionalComponent,
renderList,
onUnmounted
onUnmounted,
createElementBlock,
createElementVNode
} from '@vue/runtime-test'
import { PatchFlags, SlotFlags } from '@vue/shared'
import { SuspenseImpl } from '../src/components/Suspense'
Expand Down Expand Up @@ -697,6 +699,81 @@ describe('renderer: optimized mode', () => {
)
})

test('force full diff slot and fallback nodes', async () => {
const Comp = {
props: ['show'],
setup(props: any, { slots }: SetupContext) {
return () => {
return (
openBlock(),
createElementBlock('div', null, [
renderSlot(slots, 'default', { hide: !props.show }, () => [
true
? (openBlock(),
(block = createElementBlock(
Fragment,
{ key: 0 },
[createTextVNode('foo')],
PatchFlags.STABLE_FRAGMENT
)))
: createCommentVNode('v-if', true)
])
])
)
}
}
}

const show = ref(true)
const app = createApp({
render() {
return (
openBlock(),
createBlock(
Comp,
{ show: show.value },
{
default: withCtx(({ hide }: { hide: boolean }) => [
!hide
? (openBlock(),
createElementBlock(
Fragment,
{ key: 0 },
[
createCommentVNode('comment'),
createElementVNode(
'div',
null,
'bar',
PatchFlags.HOISTED
)
],
PatchFlags.STABLE_FRAGMENT
))
: createCommentVNode('v-if', true)
]),
_: SlotFlags.STABLE
},
PatchFlags.PROPS,
['show']
)
)
}
})

app.mount(root)
expect(inner(root)).toBe('<div><!--comment--><div>bar</div></div>')
expect(block).toBe(null)

show.value = false
await nextTick()
expect(inner(root)).toBe('<div>foo</div>')

show.value = true
await nextTick()
expect(inner(root)).toBe('<div><!--comment--><div>bar</div></div>')
})

// 3569
test('should force bailout when the user manually calls the slot function', async () => {
const index = ref(0)
Expand Down
13 changes: 11 additions & 2 deletions packages/runtime-core/src/helpers/renderSlot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ export function renderSlot(
currentRenderingInstance!.parent.isCE)
) {
if (name !== 'default') props.name = name
return createVNode('slot', props, fallback && fallback())
let renderFallback = false
const node = createVNode(
'slot',
props,
fallback && ((renderFallback = true), fallback())
)
if (renderFallback) node.patchFlag = PatchFlags.BAIL
return node
}

let slot = slots[name]
Expand All @@ -59,6 +66,7 @@ export function renderSlot(
if (slot && (slot as ContextualRenderFn)._c) {
;(slot as ContextualRenderFn)._d = false
}
let renderFallback = false
openBlock()
const validSlotContent = slot && ensureValidVNode(slot(props))
const rendered = createBlock(
Expand All @@ -71,7 +79,7 @@ export function renderSlot(
(validSlotContent && (validSlotContent as any).key) ||
`_${name}`
},
validSlotContent || (fallback ? fallback() : []),
validSlotContent || (fallback ? ((renderFallback = true), fallback()) : []),
validSlotContent && (slots as RawSlots)._ === SlotFlags.STABLE
? PatchFlags.STABLE_FRAGMENT
: PatchFlags.BAIL
Expand All @@ -82,6 +90,7 @@ export function renderSlot(
if (slot && (slot as ContextualRenderFn)._c) {
;(slot as ContextualRenderFn)._d = true
}
if (renderFallback) rendered.patchFlag = PatchFlags.BAIL
return rendered
}

Expand Down
10 changes: 6 additions & 4 deletions packages/runtime-core/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ function baseCreateRenderer(
}

const areChildrenSVG = isSVG && n2.type !== 'foreignObject'
if (dynamicChildren) {
if (optimized && dynamicChildren) {
patchBlockChildren(
n1.dynamicChildren!,
dynamicChildren,
Expand Down Expand Up @@ -1058,9 +1058,10 @@ function baseCreateRenderer(
let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2

if (
__DEV__ &&
// #5523 dev root fragment may inherit directives
(isHmrUpdating || patchFlag & PatchFlags.DEV_ROOT_FRAGMENT)
(__DEV__ &&
// #5523 dev root fragment may inherit directives
(isHmrUpdating || patchFlag & PatchFlags.DEV_ROOT_FRAGMENT)) ||
(n1 || n2).patchFlag === PatchFlags.BAIL
) {
// HMR updated / Dev root fragment (w/ comments), force full diff
patchFlag = 0
Expand Down Expand Up @@ -1093,6 +1094,7 @@ function baseCreateRenderer(
)
} else {
if (
optimized &&
patchFlag > 0 &&
patchFlag & PatchFlags.STABLE_FRAGMENT &&
dynamicChildren &&
Expand Down

0 comments on commit ba26e1b

Please sign in to comment.