X_KEEP_ALIVE_INVALID_CHILDREN,
X_V_SKIP_NO_EXPRESSION,
X_V_SKIP_ON_TEMPLATE,
+ X_V_SKIP_UNEXPECTED_SLOT,
// generic errors
X_PREFIX_ID_NOT_SUPPORTED,
[ErrorCodes.X_VNODE_HOOKS]: `@vnode-* hooks in templates are no longer supported. Use the vue: prefix instead. For example, @vnode-mounted should be changed to @vue:mounted. @vnode-* hooks support has been removed in 3.4.`,
[ErrorCodes.X_V_SKIP_NO_EXPRESSION]: `v-skip is missing expression.`,
[ErrorCodes.X_V_SKIP_ON_TEMPLATE]: `v-skip cannot be used on <template> or <slot> tags.`,
+ [ErrorCodes.X_V_SKIP_UNEXPECTED_SLOT]: `v-skip directive requires the component to have a default slot without slot props`,
// generic errors
[ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
import {
+ ElementTypes,
type IfBranchNode,
NodeTypes,
type SimpleExpressionNode,
+ type SlotsExpression,
+ type TemplateChildNode,
createConditionalExpression,
createSimpleExpression,
} from '../ast'
export const transformSkip: NodeTransform = createStructuralDirectiveTransform(
'skip',
(node, dir, context) => {
+ const loc = dir.exp ? dir.exp.loc : node.loc
if (isTemplateNode(node) || isSlotOutlet(node)) {
- const loc = dir.exp ? dir.exp.loc : node.loc
context.onError(createCompilerError(ErrorCodes.X_V_SKIP_ON_TEMPLATE, loc))
return
}
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, dir.loc),
+ createCompilerError(ErrorCodes.X_V_SKIP_NO_EXPRESSION, loc),
)
dir.exp = createSimpleExpression(`true`, false, loc)
}
}
return () => {
+ let children: TemplateChildNode[] = []
+ // for components, extract default slot without props
+ // if not found, throw an error
+ if (node.tagType === ElementTypes.COMPONENT) {
+ const codegenNode = node.codegenNode!
+ if (codegenNode.type === NodeTypes.VNODE_CALL) {
+ const genChildren = codegenNode.children! as SlotsExpression
+ if (genChildren.type === NodeTypes.JS_OBJECT_EXPRESSION) {
+ const prop = genChildren.properties.find(
+ p =>
+ p.type === NodeTypes.JS_PROPERTY &&
+ p.key.type === NodeTypes.SIMPLE_EXPRESSION &&
+ p.key.content === 'default' &&
+ p.value.params === undefined,
+ )
+ if (prop) {
+ children = prop.value.returns as TemplateChildNode[]
+ } else {
+ context.onError(
+ createCompilerError(ErrorCodes.X_V_SKIP_UNEXPECTED_SLOT, loc),
+ )
+ }
+ }
+ }
+ }
+ // for plain elements, take all children
+ else {
+ children = node.children
+ }
const consequent: IfBranchNode = {
type: NodeTypes.IF_BRANCH,
loc: node.loc,
condition: undefined,
- children: node.children,
+ children,
userKey: findProp(node, `key`),
}
+
const alternate: IfBranchNode = {
type: NodeTypes.IF_BRANCH,
loc: node.loc,
children: [node],
userKey: findProp(node, `key`),
}
+
node.codegenNode = createConditionalExpression(
dir.exp!,
createCodegenNodeForBranch(consequent, 0, context),