feat(compiler-core): support Suspense in templates
This commit is contained in:
parent
e97951dd2e
commit
4b2b29efa1
@ -50,7 +50,8 @@ export const enum ElementTypes {
|
||||
COMPONENT,
|
||||
SLOT,
|
||||
TEMPLATE,
|
||||
PORTAL
|
||||
PORTAL,
|
||||
SUSPENSE
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
@ -101,6 +102,7 @@ export type ElementNode =
|
||||
| SlotOutletNode
|
||||
| TemplateNode
|
||||
| PortalNode
|
||||
| SuspenseNode
|
||||
|
||||
export interface BaseElementNode extends Node {
|
||||
type: NodeTypes.ELEMENT
|
||||
@ -141,6 +143,11 @@ export interface PortalNode extends BaseElementNode {
|
||||
codegenNode: ElementCodegenNode | undefined
|
||||
}
|
||||
|
||||
export interface SuspenseNode extends BaseElementNode {
|
||||
tagType: ElementTypes.SUSPENSE
|
||||
codegenNode: ElementCodegenNode | undefined
|
||||
}
|
||||
|
||||
export interface TextNode extends Node {
|
||||
type: NodeTypes.TEXT
|
||||
content: string
|
||||
|
@ -445,6 +445,8 @@ function parseTag(
|
||||
if (tag === 'slot') tagType = ElementTypes.SLOT
|
||||
else if (tag === 'template') tagType = ElementTypes.TEMPLATE
|
||||
else if (tag === 'portal' || tag === 'Portal') tagType = ElementTypes.PORTAL
|
||||
else if (tag === 'suspense' || tag === 'Suspense')
|
||||
tagType = ElementTypes.SUSPENSE
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -24,7 +24,8 @@ import {
|
||||
RESOLVE_COMPONENT,
|
||||
MERGE_PROPS,
|
||||
TO_HANDLERS,
|
||||
PORTAL
|
||||
PORTAL,
|
||||
SUSPENSE
|
||||
} from '../runtimeHelpers'
|
||||
import { getInnerRange, isVSlot, toValidAssetId } from '../utils'
|
||||
import { buildSlots } from './vSlot'
|
||||
@ -36,20 +37,20 @@ const directiveImportMap = new WeakMap<DirectiveNode, symbol>()
|
||||
|
||||
// generate a JavaScript AST for this element's codegen
|
||||
export const transformElement: NodeTransform = (node, context) => {
|
||||
if (node.type === NodeTypes.ELEMENT) {
|
||||
if (
|
||||
node.tagType === ElementTypes.ELEMENT ||
|
||||
node.tagType === ElementTypes.COMPONENT ||
|
||||
node.tagType === ElementTypes.PORTAL ||
|
||||
// <template> with v-if or v-for are ignored during traversal.
|
||||
// <template> without v-slot should be treated as a normal element.
|
||||
(node.tagType === ElementTypes.TEMPLATE && !node.props.some(isVSlot))
|
||||
node.type !== NodeTypes.ELEMENT ||
|
||||
// handled by transformSlotOutlet
|
||||
node.tagType === ElementTypes.SLOT ||
|
||||
// <template v-if/v-for> should have already been replaced
|
||||
// <templte v-slot> is handled by buildSlots
|
||||
(node.tagType === ElementTypes.TEMPLATE && node.props.some(isVSlot))
|
||||
) {
|
||||
return
|
||||
}
|
||||
// perform the work on exit, after all child expressions have been
|
||||
// processed and merged.
|
||||
return () => {
|
||||
const isComponent = node.tagType === ElementTypes.COMPONENT
|
||||
const isPortal = node.tagType === ElementTypes.PORTAL
|
||||
let hasProps = node.props.length > 0
|
||||
let patchFlag: number = 0
|
||||
let runtimeDirectives: DirectiveNode[] | undefined
|
||||
@ -63,8 +64,10 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
const args: CallExpression['arguments'] = [
|
||||
isComponent
|
||||
? toValidAssetId(node.tag, `component`)
|
||||
: isPortal
|
||||
: node.tagType === ElementTypes.PORTAL
|
||||
? context.helper(PORTAL)
|
||||
: node.tagType === ElementTypes.SUSPENSE
|
||||
? context.helper(SUSPENSE)
|
||||
: `"${node.tag}"`
|
||||
]
|
||||
// props
|
||||
@ -138,11 +141,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
}
|
||||
|
||||
const { loc } = node
|
||||
const vnode = createCallExpression(
|
||||
context.helper(CREATE_VNODE),
|
||||
args,
|
||||
loc
|
||||
)
|
||||
const vnode = createCallExpression(context.helper(CREATE_VNODE), args, loc)
|
||||
|
||||
if (runtimeDirectives && runtimeDirectives.length) {
|
||||
node.codegenNode = createCallExpression(
|
||||
@ -161,8 +160,6 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type PropsExpression = ObjectExpression | CallExpression | ExpressionNode
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user