diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index fad91a7952d..f7c38ff4524 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -35,13 +35,13 @@ export function render(_ctx) { const _directive_test = _resolveDirective("test") const n4 = _createComponentWithFallback(_component_Comp, null, { "default": () => { - const n0 = _createIf(() => (true), () => { + const n0 = _createIf(() => (true) ? () => { const n3 = t0() const n2 = _createComponentWithFallback(_component_Bar) _withDirectives(n2, [[_directive_hello, void 0, void 0, { world: true }]]) _insert(n2, n3) return n3 - }) + } : undefined) return n0 } }, true) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap index da863b2407f..6daa919b8ca 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap @@ -34,11 +34,11 @@ const t0 = _template("
", true) export function render(_ctx) { const _setTemplateRef = _createTemplateRefSetter() - const n0 = _createIf(() => (true), () => { + const n0 = _createIf(() => (true) ? () => { const n2 = t0() _setTemplateRef(n2, "foo") return n2 - }) + } : undefined) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap index a01ec4774d5..bf02b33c0cc 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vIf.spec.ts.snap @@ -5,11 +5,11 @@ exports[`compiler: v-if > basic v-if 1`] = ` const t0 = _template("
", true) export function render(_ctx) { - const n0 = _createIf(() => (_ctx.ok), () => { + const n0 = _createIf(() => (_ctx.ok) ? () => { const n2 = t0() _renderEffect(() => _setText(n2, _ctx.msg)) return n2 - }) + } : undefined) return n0 }" `; @@ -25,18 +25,18 @@ const t5 = _template("") export function render(_ctx) { const n13 = t5() - const n0 = _createIf(() => (_ctx.ok), () => { + const n0 = _createIf(() => (_ctx.ok) ? () => { const n2 = t0() return n2 - }, () => _createIf(() => (_ctx.orNot), () => { + } : (_ctx.orNot) ? () => { const n5 = t1() const n6 = t2() return [n5, n6] - }, () => { + } : () => { const n10 = t3() const n11 = t4() return [n10, n11] - })) + }) _renderEffect(() => _setText(n13, _ctx.text)) return [n0, n13] }" @@ -47,14 +47,14 @@ exports[`compiler: v-if > dedupe same template 1`] = ` const t0 = _template("
hello
") export function render(_ctx) { - const n0 = _createIf(() => (_ctx.ok), () => { + const n0 = _createIf(() => (_ctx.ok) ? () => { const n2 = t0() return n2 - }) - const n3 = _createIf(() => (_ctx.ok), () => { + } : undefined) + const n3 = _createIf(() => (_ctx.ok) ? () => { const n5 = t0() return n5 - }) + } : undefined) return [n0, n3] }" `; @@ -66,13 +66,13 @@ const t1 = _template("hello") const t2 = _template("

", true) export function render(_ctx) { - const n0 = _createIf(() => (_ctx.ok), () => { + const n0 = _createIf(() => (_ctx.ok) ? () => { const n2 = t0() const n3 = t1() const n4 = t2() _renderEffect(() => _setText(n4, _ctx.msg)) return [n2, n3, n4] - }) + } : undefined) return n0 }" `; @@ -83,10 +83,10 @@ const t0 = _template("
") const t1 = _template("

") export function render(_ctx) { - const n0 = _createIf(() => (_ctx.ok), () => { + const n0 = _createIf(() => (_ctx.ok) ? () => { const n2 = t0() return n2 - }, () => { + } : () => { const n4 = t1() return n4 }) @@ -101,16 +101,16 @@ const t1 = _template("

") const t2 = _template("fine") export function render(_ctx) { - const n0 = _createIf(() => (_ctx.ok), () => { + const n0 = _createIf(() => (_ctx.ok) ? () => { const n2 = t0() return n2 - }, () => _createIf(() => (_ctx.orNot), () => { + } : (_ctx.orNot) ? () => { const n4 = t1() return n4 - }, () => { + } : () => { const n7 = t2() return n7 - })) + }) return n0 }" `; @@ -121,13 +121,13 @@ const t0 = _template("
") const t1 = _template("

") export function render(_ctx) { - const n0 = _createIf(() => (_ctx.ok), () => { + const n0 = _createIf(() => (_ctx.ok) ? () => { const n2 = t0() return n2 - }, () => _createIf(() => (_ctx.orNot), () => { + } : (_ctx.orNot) ? () => { const n4 = t1() return n4 - })) + } : undefined) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap index 39384169e10..64547034cfc 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap @@ -78,10 +78,10 @@ exports[`compiler: v-once > with v-if 1`] = ` const t0 = _template("
", true) export function render(_ctx) { - const n0 = _createIf(() => (_ctx.expr), () => { + const n0 = _createIf(() => (_ctx.expr) ? () => { const n2 = t0() return n2 - }, null, true) + } : undefined, true) return n0 }" `; @@ -92,10 +92,10 @@ const t0 = _template("
") const t1 = _template("

") export function render(_ctx) { - const n0 = _createIf(() => (_ctx.expr), () => { + const n0 = _createIf(() => (_ctx.expr) ? () => { const n2 = t0() return n2 - }, () => { + } : () => { const n4 = t1() return n4 }, true) diff --git a/packages/compiler-vapor/src/generators/if.ts b/packages/compiler-vapor/src/generators/if.ts index f4a3e599fab..d6b320d66d9 100644 --- a/packages/compiler-vapor/src/generators/if.ts +++ b/packages/compiler-vapor/src/generators/if.ts @@ -13,8 +13,8 @@ export function genIf( const { condition, positive, negative, once } = oper const [frag, push] = buildCodeFragment() - const conditionExpr: CodeFragment[] = [ - '() => (', + const codes: CodeFragment[] = [ + isNested ? '(' : '() => (', ...genExpression(condition, context), ')', ] @@ -23,23 +23,27 @@ export function genIf( let negativeArg: false | CodeFragment[] = false if (negative) { + positiveArg.unshift(' ? ') + negativeArg = [' : '] if (negative.type === IRNodeTypes.BLOCK) { - negativeArg = genBlock(negative, context) + negativeArg.push(...genBlock(negative, context)) } else { - negativeArg = ['() => ', ...genIf(negative!, context, true)] + negativeArg.push(...genIf(negative!, context, true)) } + } else { + positiveArg.unshift(' ? ') + positiveArg.push(' : undefined') } - if (!isNested) push(NEWLINE, `const n${oper.id} = `) - push( - ...genCall( - helper('createIf'), - conditionExpr, - positiveArg, - negativeArg, - once && 'true', - ), - ) + codes.push(...positiveArg) + if (negativeArg) codes.push(...negativeArg) + + if (isNested) { + push(...codes) + } else { + push(NEWLINE, `const n${oper.id} = `) + push(...genCall(helper('createIf'), codes, once && 'true')) + } return frag } diff --git a/packages/runtime-vapor/__tests__/apiLifecycle.spec.ts b/packages/runtime-vapor/__tests__/apiLifecycle.spec.ts index af9f10f9f42..1cc2e463c73 100644 --- a/packages/runtime-vapor/__tests__/apiLifecycle.spec.ts +++ b/packages/runtime-vapor/__tests__/apiLifecycle.spec.ts @@ -138,9 +138,8 @@ describe('api: lifecycle hooks', () => { const { render, host } = define({ setup() { // @ts-expect-error - const n0 = createIf( - () => toggle.value, - () => createComponent(Child), + const n0 = createIf(() => + toggle.value ? () => createComponent(Child) : undefined, ) return n0 }, @@ -172,9 +171,8 @@ describe('api: lifecycle hooks', () => { const { render, host } = define({ setup() { // @ts-expect-error - const n0 = createIf( - () => toggle.value, - () => createComponent(Child), + const n0 = createIf(() => + toggle.value ? () => createComponent(Child) : undefined, ) return n0 }, @@ -206,9 +204,8 @@ describe('api: lifecycle hooks', () => { const { render, host } = define({ setup() { // @ts-expect-error - const n0 = createIf( - () => toggle.value, - () => createComponent(Child), + const n0 = createIf(() => + toggle.value ? () => createComponent(Child) : undefined, ) return n0 }, @@ -249,9 +246,10 @@ describe('api: lifecycle hooks', () => { onUnmounted(() => calls.push('onUnmounted')) // @ts-expect-error - const n0 = createIf( - () => toggle.value, - () => createComponent(Mid, { count: () => count.value }), + const n0 = createIf(() => + toggle.value + ? () => createComponent(Mid, { count: () => count.value }) + : undefined, ) return n0 }, @@ -428,9 +426,10 @@ describe('api: lifecycle hooks', () => { const { render } = define({ setup() { // @ts-expect-error - return createIf( - () => toggle.value, - () => [createComponent(Child), createComponent(Child)], + return createIf(() => + toggle.value + ? () => [createComponent(Child), createComponent(Child)] + : undefined, ) }, }) diff --git a/packages/runtime-vapor/__tests__/componentSlots.spec.ts b/packages/runtime-vapor/__tests__/componentSlots.spec.ts index f4ff0c31cba..5f1e7929d9f 100644 --- a/packages/runtime-vapor/__tests__/componentSlots.spec.ts +++ b/packages/runtime-vapor/__tests__/componentSlots.spec.ts @@ -447,11 +447,12 @@ describe('component: slots', () => { setup() { return createComponent(Child, null, { default: () => { - return createIf( - () => toggle.value, - () => { - return document.createTextNode('content') - }, + return createIf(() => + toggle.value + ? () => { + return document.createTextNode('content') + } + : () => [], ) }, }) diff --git a/packages/runtime-vapor/__tests__/dom/templateRef.spec.ts b/packages/runtime-vapor/__tests__/dom/templateRef.spec.ts index a9a116f8a55..41f637d9333 100644 --- a/packages/runtime-vapor/__tests__/dom/templateRef.spec.ts +++ b/packages/runtime-vapor/__tests__/dom/templateRef.spec.ts @@ -89,13 +89,14 @@ describe('api: template ref', () => { }, render() { const setRef = createTemplateRefSetter() - const n0 = createIf( - () => toggle.value, - () => { - const n1 = t0() - setRef(n1 as Element, 'refKey') - return n1 - }, + const n0 = createIf(() => + toggle.value + ? () => { + const n1 = t0() + setRef(n1 as Element, 'refKey') + return n1 + } + : undefined, ) return n0 }, @@ -160,13 +161,14 @@ describe('api: template ref', () => { const t0 = template('
') const { render } = define({ render() { - const n0 = createIf( - () => toggle.value, - () => { - const n1 = t0() - createTemplateRefSetter()(n1 as Element, fn) - return n1 - }, + const n0 = createIf(() => + toggle.value + ? () => { + const n1 = t0() + createTemplateRefSetter()(n1 as Element, fn) + return n1 + } + : undefined, ) return n0 }, @@ -371,18 +373,18 @@ describe('api: template ref', () => { render() { const instance = currentInstance! const setRef = createTemplateRefSetter() - const n0 = createIf( - () => refToggle.value, - () => { - const n1 = t0() - setRef(n1 as Element, 'foo') - return n1 - }, - () => { - const n1 = t1() - setRef(n1 as Element, 'foo') - return n1 - }, + const n0 = createIf(() => + refToggle.value + ? () => { + const n1 = t0() + setRef(n1 as Element, 'foo') + return n1 + } + : () => { + const n1 = t1() + setRef(n1 as Element, 'foo') + return n1 + }, ) watchEffect( () => { @@ -416,30 +418,31 @@ describe('api: template ref', () => { const t1 = template('
  • ') const { render } = define({ render() { - const n0 = createIf( - () => show.value, - () => { - const n1 = t0() - const n2 = createFor( - () => list, - state => { - const n1 = t1() - createTemplateRefSetter()( - n1 as Element, - listRefs, - undefined, - true, + const n0 = createIf(() => + show.value + ? () => { + const n1 = t0() + const n2 = createFor( + () => list, + state => { + const n1 = t1() + createTemplateRefSetter()( + n1 as Element, + listRefs, + undefined, + true, + ) + renderEffect(() => { + const [item] = state + setText(n1, item) + }) + return n1 + }, ) - renderEffect(() => { - const [item] = state - setText(n1, item) - }) + insert(n2, n1 as ParentNode) return n1 - }, - ) - insert(n2, n1 as ParentNode) - return n1 - }, + } + : undefined, ) return n0 }, @@ -479,30 +482,31 @@ describe('api: template ref', () => { return { listRefs } }, render() { - const n0 = createIf( - () => show.value, - () => { - const n1 = t0() - const n2 = createFor( - () => list, - state => { - const n1 = t1() - createTemplateRefSetter()( - n1 as Element, - 'listRefs', - undefined, - true, + const n0 = createIf(() => + show.value + ? () => { + const n1 = t0() + const n2 = createFor( + () => list, + state => { + const n1 = t1() + createTemplateRefSetter()( + n1 as Element, + 'listRefs', + undefined, + true, + ) + renderEffect(() => { + const [item] = state + setText(n1, item) + }) + return n1 + }, ) - renderEffect(() => { - const [item] = state - setText(n1, item) - }) + insert(n2, n1 as ParentNode) return n1 - }, - ) - insert(n2, n1 as ParentNode) - return n1 - }, + } + : undefined, ) return n0 }, diff --git a/packages/runtime-vapor/__tests__/if.spec.ts b/packages/runtime-vapor/__tests__/if.spec.ts index a7e6266a7e1..f768d0f7c96 100644 --- a/packages/runtime-vapor/__tests__/if.spec.ts +++ b/packages/runtime-vapor/__tests__/if.spec.ts @@ -38,21 +38,21 @@ describe('createIf', () => { const n0 = t0() insert( - createIf( - spyConditionFn, - // v-if - (spyIfFn ||= vi.fn(() => { - const n2 = t1() - renderEffect(() => { - setText(n2, count.value) - }) - return n2 - })), - // v-else - (spyElseFn ||= vi.fn(() => { - const n4 = t2() - return n4 - })), + createIf(() => + spyConditionFn() + ? // v-if + (spyIfFn ||= vi.fn(() => { + const n2 = t1() + renderEffect(() => { + setText(n2, count.value) + }) + return n2 + })) + : // v-else + (spyElseFn ||= vi.fn(() => { + const n4 = t2() + return n4 + })), ), n0 as any as ParentNode, ) @@ -61,7 +61,7 @@ describe('createIf', () => { expect(host.innerHTML).toBe('

    zero

    ') expect(spyConditionFn).toHaveBeenCalledTimes(1) - expect(spyIfFn!).toHaveBeenCalledTimes(0) + expect(spyIfFn!).toBeUndefined() expect(spyElseFn!).toHaveBeenCalledTimes(1) count.value++ @@ -98,19 +98,21 @@ describe('createIf', () => { const t0 = template('Vapor') const t1 = template('Hello ') const { host } = define(() => { - const n1 = createIf( - () => ok1.value, - () => { - const n2 = t1() - const n3 = createIf( - () => ok2.value, - () => { - const n4 = t0() - return n4 - }, - ) - return [n2, n3] - }, + const n1 = createIf(() => + ok1.value + ? () => { + const n2 = t1() + const n3 = createIf(() => + ok2.value + ? () => { + const n4 = t0() + return n4 + } + : undefined, + ) + return [n2, n3] + } + : undefined, ) return n1 }).render() @@ -158,29 +160,29 @@ describe('createIf', () => { const t0 = template('

    ') const { instance } = define(() => { - const n1 = createIf( - spyConditionFn1, - () => { - const n2 = t0() - withDirectives(children(n2, 0), [ - [vDirective, () => (update.value, '1')], - ]) - return n2 - }, - () => - createIf( - spyConditionFn2, - () => { + const n1 = createIf(() => + spyConditionFn1() + ? () => { const n2 = t0() - withDirectives(children(n2, 0), [[vDirective, () => '2']]) + withDirectives(children(n2, 0), [ + [vDirective, () => (update.value, '1')], + ]) return n2 - }, - () => { - const n2 = t0() - withDirectives(children(n2, 0), [[vDirective, () => '3']]) - return n2 - }, - ), + } + : () => + createIf(() => + spyConditionFn2() + ? () => { + const n2 = t0() + withDirectives(children(n2, 0), [[vDirective, () => '2']]) + return n2 + } + : () => { + const n2 = t0() + withDirectives(children(n2, 0), [[vDirective, () => '3']]) + return n2 + }, + ), ) return [n1] }).render() diff --git a/packages/runtime-vapor/src/apiCreateIf.ts b/packages/runtime-vapor/src/apiCreateIf.ts index e4035313931..fb2c4881205 100644 --- a/packages/runtime-vapor/src/apiCreateIf.ts +++ b/packages/runtime-vapor/src/apiCreateIf.ts @@ -2,17 +2,15 @@ import { type BlockFn, DynamicFragment } from './block' import { renderEffect } from './renderEffect' export function createIf( - condition: () => any, - b1: BlockFn, - b2?: BlockFn, + ifBlockGetter: () => BlockFn | undefined, once?: boolean, // hydrationNode?: Node, ): DynamicFragment { const frag = __DEV__ ? new DynamicFragment('if') : new DynamicFragment() if (once) { - frag.update(condition() ? b1 : b2) + frag.update(ifBlockGetter()) } else { - renderEffect(() => frag.update(condition() ? b1 : b2)) + renderEffect(() => frag.update(ifBlockGetter())) } return frag }