From 32ac9ed0d5463211321bd4ab157c961c9126186c Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 22 Jan 2025 16:34:00 +0800 Subject: [PATCH] wip: ssr v-skip --- .../src/transforms/ssrTransformComponent.ts | 8 +++ .../src/transforms/ssrTransformElement.ts | 7 +++ .../compiler-ssr/src/transforms/ssrVIf.ts | 2 +- .../compiler-ssr/src/transforms/ssrVSkip.ts | 49 +++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 packages/compiler-ssr/src/transforms/ssrVSkip.ts diff --git a/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts b/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts index cad1ee81028..6e00788e6b0 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts @@ -34,6 +34,7 @@ import { createRoot, createSimpleExpression, createTransformContext, + findDir, getBaseTransformPreset, locStub, resolveComponentType, @@ -61,6 +62,7 @@ import { ssrProcessTransition, ssrTransformTransition, } from './ssrTransformTransition' +import { ssrProcessSkip } from './ssrVSkip' // We need to construct the slot functions in the 1st pass to ensure proper // scope tracking, but the children of each slot cannot be processed until @@ -206,6 +208,12 @@ export function ssrProcessComponent( context: SSRTransformContext, parent: { children: TemplateChildNode[] }, ): void { + const skipDir = findDir(node, 'skip') + if (skipDir) { + ssrProcessSkip(node, skipDir, context) + return + } + const component = componentTypeMap.get(node)! if (!node.ssrCodegenNode) { // this is a built-in component that fell-through. diff --git a/packages/compiler-ssr/src/transforms/ssrTransformElement.ts b/packages/compiler-ssr/src/transforms/ssrTransformElement.ts index 4a12b0f7ba7..5ff86593642 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformElement.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformElement.ts @@ -57,6 +57,7 @@ import { type SSRTransformContext, processChildren, } from '../ssrCodegenTransform' +import { ssrProcessSkip } from './ssrVSkip' // for directives with children overwrite (e.g. v-html & v-text), we need to // store the raw children so that they can be added in the 2nd pass. @@ -442,6 +443,12 @@ export function ssrProcessElement( node: PlainElementNode, context: SSRTransformContext, ): void { + const skipDir = findDir(node, 'skip') + if (skipDir) { + ssrProcessSkip(node, skipDir, context) + return + } + const isVoidTag = context.options.isVoidTag || NO const elementsToAdd = node.ssrCodegenNode!.elements for (let j = 0; j < elementsToAdd.length; j++) { diff --git a/packages/compiler-ssr/src/transforms/ssrVIf.ts b/packages/compiler-ssr/src/transforms/ssrVIf.ts index 0e3880247a1..c84ca659784 100644 --- a/packages/compiler-ssr/src/transforms/ssrVIf.ts +++ b/packages/compiler-ssr/src/transforms/ssrVIf.ts @@ -63,7 +63,7 @@ export function ssrProcessIf( } } -function processIfBranch( +export function processIfBranch( branch: IfBranchNode, context: SSRTransformContext, disableNestedFragments = false, diff --git a/packages/compiler-ssr/src/transforms/ssrVSkip.ts b/packages/compiler-ssr/src/transforms/ssrVSkip.ts new file mode 100644 index 00000000000..1780a189d10 --- /dev/null +++ b/packages/compiler-ssr/src/transforms/ssrVSkip.ts @@ -0,0 +1,49 @@ +import { + type ComponentNode, + type DirectiveNode, + ErrorCodes, + type IfBranchNode, + NodeTypes, + type PlainElementNode, + type SimpleExpressionNode, + createCompilerError, + createIfStatement, + createSimpleExpression, +} from '@vue/compiler-core' +import { processIfBranch } from './ssrVIf' +import type { SSRTransformContext } from '../ssrCodegenTransform' + +export function ssrProcessSkip( + node: PlainElementNode | ComponentNode, + dir: DirectiveNode, + context: SSRTransformContext, +): void { + if (!dir.exp || !(dir.exp as SimpleExpressionNode).content.trim()) { + const loc = dir.exp ? dir.exp.loc : node.loc + context.onError(createCompilerError(ErrorCodes.X_V_SKIP_NO_EXPRESSION, loc)) + dir.exp = createSimpleExpression(`true`, false, loc) + } + + node.props = node.props.filter(x => x.name !== 'skip') + const consequent: IfBranchNode = { + type: NodeTypes.IF_BRANCH, + loc: node.loc, + condition: undefined, + children: node.children, + } + + const alternate: IfBranchNode = { + type: NodeTypes.IF_BRANCH, + loc: node.loc, + condition: undefined, + children: [node], + } + + const ifNode = createIfStatement( + dir.exp!, + processIfBranch(consequent, context), + processIfBranch(alternate, context), + ) + + context.pushStatement(ifNode) +}