if (!currentIf.alternate && !disableComment) {
currentIf.alternate = createBlockStatement([
- createCallExpression(`_push`, ['`<!---->`']),
+ createCallExpression(`_push`, [
+ isVapor ? `\`<!--${IF_ANCHOR_LABEL}-->\`` : '`<!---->`',
+ ]),
])
}
}
undefined,
data,
)
- // v-if="false" is rendered as <!----> in the server-rendered HTML
- // it reused as anchor, so the anchor label is empty
- expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`"<!---->"`)
+ expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
+ `"<!--if-->"`,
+ )
data.value = true
await nextTick()
expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
- `"<div>foo</div><!---->"`,
+ `"<div>foo</div><!--if-->"`,
)
})
)
})
+ test('nested components (VDOM -> Vapor(with slot fallback) -> Vapor)', async () => {
+ const data = ref(true)
+ const { container } = await testHydrationInterop(
+ `<script setup>const data = _data; const components = _components;</script>
+ <template>
+ <components.VaporChild/>
+ </template>`,
+ {
+ VaporChild: {
+ code: `<template>
+ <components.VaporChild2>
+ <template #default>
+ <span>{{data}} vapor fallback</span>
+ </template>
+ </components.VaporChild2>
+ </template>`,
+ vapor: true,
+ },
+ VaporChild2: {
+ code: `<template><slot><span>vapor fallback2</span></slot></template>`,
+ vapor: true,
+ },
+ },
+ data,
+ )
+
+ expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
+ `
+ "
+ <!--[--><span>true vapor fallback</span><!--]-->
+ <!--slot-->"
+ `,
+ )
+
+ data.value = false
+ await nextTick()
+ expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
+ `
+ "
+ <!--[--><span>false vapor fallback</span><!--]-->
+ <!--slot-->"
+ `,
+ )
+ })
+
test('vapor slot render vdom component', async () => {
const data = ref(true)
const { container } = await testHydrationInterop(
currentHydrationNode!,
FOR_ANCHOR_LABEL,
)!
- if (__DEV__ && !parentAnchor) {
- // this should not happen
+ if (
+ (__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
+ !parentAnchor
+ ) {
throw new Error(`v-for fragment anchor node was not found.`)
}
}
update(render?: BlockFn, key: any = render): void {
if (key === this.current) {
- if (isHydrating) this.hydrate(this.anchorLabel!, true)
+ if (isHydrating) this.hydrate(this.anchorLabel!)
return
}
this.current = key
if (isHydrating) this.hydrate(this.anchorLabel!)
}
- hydrate = (label: string, isEmpty: boolean = false): void => {
+ hydrate = (label: string): void => {
// avoid repeated hydration during rendering fallback
if (this.anchor) return
- // for `v-if="false"`, the node will be an empty comment, use it as the anchor.
- // otherwise, find next sibling vapor fragment anchor
- if (label === 'if' && isEmpty) {
- this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, '')!
- } else {
- this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, label)!
-
- // forwarded slots anchors are not present in ssr vnode-based slot
- if (
- !this.anchor &&
- this.nodes instanceof DynamicFragment &&
- this.nodes.forwarded
- ) {
- const { parentNode, nextSibling } = this.nodes.anchor
- parentNode!.insertBefore(
- (this.anchor = __DEV__ ? createComment(label) : createTextNode()),
- nextSibling,
- )
- }
- }
-
+ this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, label)!
if (this.anchor) {
advanceHydrationNode(this.anchor)
- } else if (__DEV__) {
+ } else if (__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) {
throw new Error(`${label} fragment anchor node was not found.`)
}
}
import { type Block, type VaporTransitionHooks, insert, remove } from './block'
import {
EMPTY_OBJ,
- SLOT_ANCHOR_LABEL,
extend,
isArray,
isFunction,
},
hydrate(vnode, node, container, anchor, parentComponent) {
- vaporHydrateNode(node, () => {
- this.mount(vnode, container, anchor, parentComponent)
- })
+ vaporHydrateNode(node, () =>
+ this.mount(vnode, container, anchor, parentComponent),
+ )
return _next(node)
},
vnode.vb = slot(new Proxy(propsRef, vaporSlotPropsProxyHandler))
vnode.el = vnode.anchor = locateVaporFragmentAnchor(
currentHydrationNode!,
- SLOT_ANCHOR_LABEL,
+ // there is not vapor slot anchor (<!--slot-->) injected in vdom component,
+ // so here use the fragment end anchor label
+ ']',
)
+
+ if (
+ (__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
+ !vnode.anchor
+ ) {
+ throw new Error(`vapor slot anchor node was not found.`)
+ }
})
return _next(node)
},