feat(compiler): block optimization codegen for RootNode
This commit is contained in:
@@ -27,7 +27,7 @@ import {
|
||||
TO_HANDLERS
|
||||
} from '../runtimeConstants'
|
||||
import { getInnerRange } from '../utils'
|
||||
import { buildSlots } from './vSlot'
|
||||
import { buildSlots, isVSlot } from './vSlot'
|
||||
|
||||
const toValidId = (str: string): string => str.replace(/[^\w]/g, '')
|
||||
|
||||
@@ -36,7 +36,10 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
if (node.type === NodeTypes.ELEMENT) {
|
||||
if (
|
||||
node.tagType === ElementTypes.ELEMENT ||
|
||||
node.tagType === ElementTypes.COMPONENT
|
||||
node.tagType === ElementTypes.COMPONENT ||
|
||||
// <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))
|
||||
) {
|
||||
// perform the work on exit, after all child expressions have been
|
||||
// processed and merged.
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
CallExpression
|
||||
} from '../ast'
|
||||
import { createCompilerError, ErrorCodes } from '../errors'
|
||||
import { getInnerRange, findProp } from '../utils'
|
||||
import { getInnerRange, findProp, createBlockExpression } from '../utils'
|
||||
import {
|
||||
RENDER_LIST,
|
||||
OPEN_BLOCK,
|
||||
@@ -69,7 +69,8 @@ export const transformFor = createStructuralDirectiveTransform(
|
||||
valueAlias: value,
|
||||
keyAlias: key,
|
||||
objectIndexAlias: index,
|
||||
children: [node],
|
||||
children:
|
||||
node.tagType === ElementTypes.TEMPLATE ? node.children : [node],
|
||||
codegenNode
|
||||
})
|
||||
|
||||
@@ -126,6 +127,8 @@ export const transformFor = createStructuralDirectiveTransform(
|
||||
}
|
||||
let childBlockChildren: TemplateChildNode[] | CallExpression =
|
||||
node.children
|
||||
// if the only child is a <slot/>, use it directly as fragment
|
||||
// children since it already returns an array.
|
||||
if (childBlockChildren.length === 1) {
|
||||
const child = childBlockChildren[0]
|
||||
if (
|
||||
@@ -135,22 +138,17 @@ export const transformFor = createStructuralDirectiveTransform(
|
||||
childBlockChildren = child.codegenNode!
|
||||
}
|
||||
}
|
||||
childBlock = createSequenceExpression([
|
||||
createCallExpression(helper(OPEN_BLOCK)),
|
||||
createCallExpression(helper(CREATE_BLOCK), [
|
||||
helper(FRAGMENT),
|
||||
childBlockProps,
|
||||
childBlockChildren
|
||||
])
|
||||
])
|
||||
childBlock = createBlockExpression(
|
||||
[helper(FRAGMENT), childBlockProps, childBlockChildren],
|
||||
context
|
||||
)
|
||||
} else {
|
||||
// Normal element v-for. Directly use the child's codegenNode,
|
||||
// Normal element v-for. Directly use the child's codegenNode arguments,
|
||||
// but replace createVNode() with createBlock()
|
||||
node.codegenNode!.callee = helper(CREATE_BLOCK)
|
||||
childBlock = createSequenceExpression([
|
||||
createCallExpression(helper(OPEN_BLOCK)),
|
||||
node.codegenNode!
|
||||
])
|
||||
childBlock = createBlockExpression(
|
||||
node.codegenNode!.arguments,
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
renderExp.arguments.push(
|
||||
|
||||
@@ -17,7 +17,7 @@ import { TransformContext, NodeTransform } from '../transform'
|
||||
import { createCompilerError, ErrorCodes } from '../errors'
|
||||
import { isString } from '@vue/shared'
|
||||
|
||||
const isVSlot = (p: ElementNode['props'][0]): p is DirectiveNode =>
|
||||
export const isVSlot = (p: ElementNode['props'][0]): p is DirectiveNode =>
|
||||
p.type === NodeTypes.DIRECTIVE && p.name === 'slot'
|
||||
|
||||
// A NodeTransform that tracks scope identifiers for scoped slots so that they
|
||||
|
||||
Reference in New Issue
Block a user