}"
`;
+exports[`compiler: v-if > template v-if (with v-for on same element) 1`] = `
+"import { txt as _txt, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, createIf as _createIf, template as _template } from 'vue';
+const t0 = _template("<div> ")
+
+export function render(_ctx) {
+ const n0 = _createIf(() => (_ctx.arr.length > 0), () => {
+ const n2 = _createFor(() => (_ctx.arr), (_for_item0, _for_key0) => {
+ const n4 = t0()
+ const x4 = _txt(n4)
+ _renderEffect(() => _setText(x4, "item: " + _toDisplayString(_for_item0.value)))
+ return n4
+ }, (item, index) => (index))
+ return n2
+ })
+ return n0
+}"
+`;
+
exports[`compiler: v-if > template v-if + normal v-else 1`] = `
"import { createIf as _createIf, template as _template } from 'vue';
const t0 = _template("<div>hi")
expect([...ir.template.keys()]).toMatchObject(['<div>'])
})
+ test('template v-if (with v-for on same element)', () => {
+ const { code, ir, helpers } = compileWithVIf(
+ `<template v-if="arr.length > 0" v-for="(item, index) in arr" :key="index">
+ <div>item: {{ item }}</div>
+ </template>`,
+ )
+
+ expect(code).toMatchSnapshot()
+ // should generate both createIf and createFor
+ expect(helpers).toContain('createIf')
+ expect(helpers).toContain('createFor')
+ // v-if should wrap v-for
+ const op = ir.block.dynamic.children[0].operation
+ expect(op).toMatchObject({
+ type: IRNodeTypes.IF,
+ })
+ })
+
test('template v-if + normal v-else', () => {
const { code, ir } = compileWithVIf(
`<template v-if="foo"><div>hi</div><div>ho</div></template><div v-else/>`,
})
export function wrapTemplate(node: ElementNode, dirs: string[]): TemplateNode {
+ // If the node is already a template, check if it has other structural directives
+ // that should be preserved (e.g., v-for when we're processing v-if)
if (node.tagType === ElementTypes.TEMPLATE) {
- return node
+ // Check if there are other structural directives that are NOT in the current dirs list
+ const otherStructuralDirs = ['if', 'else-if', 'else', 'for']
+ const hasOtherStructuralDir = node.props.some(
+ prop =>
+ prop.type === NodeTypes.DIRECTIVE &&
+ otherStructuralDirs.includes(prop.name) &&
+ !dirs.includes(prop.name),
+ )
+
+ // If no other structural directives, just return the node as is
+ if (!hasOtherStructuralDir) {
+ return node
+ }
+
+ // Otherwise, we need to wrap it: keep the current directive on the wrapper,
+ // and pass the rest (including the other structural directive) to the child
+ const reserved: Array<AttributeNode | DirectiveNode> = []
+ const pass: Array<AttributeNode | DirectiveNode> = []
+ node.props.forEach(prop => {
+ if (prop.type === NodeTypes.DIRECTIVE && dirs.includes(prop.name)) {
+ reserved.push(prop)
+ } else {
+ pass.push(prop)
+ }
+ })
+
+ return extend({}, node, {
+ type: NodeTypes.ELEMENT,
+ tag: 'template',
+ props: reserved,
+ tagType: ElementTypes.TEMPLATE,
+ children: [extend({}, node, { props: pass } as TemplateChildNode)],
+ } as Partial<TemplateNode>)
}
const reserved: Array<AttributeNode | DirectiveNode> = []