InterpolationNode,
CompoundExpressionNode,
createCallExpression,
- CallExpression
+ CallExpression,
+ ElementTypes
} from '../ast'
import { CREATE_TEXT } from '../runtimeHelpers'
import { PatchFlags, PatchFlagNames } from '@vue/shared'
}
}
- if (hasText && children.length > 1) {
- // when an element has mixed text/element children, convert text nodes
- // into createTextVNode(text) calls.
- for (let i = 0; i < children.length; i++) {
- const child = children[i]
- if (isText(child) || child.type === NodeTypes.COMPOUND_EXPRESSION) {
- const callArgs: CallExpression['arguments'] = []
- // createTextVNode defaults to single whitespace, so if it is a
- // single space the code could be an empty call to save bytes.
- if (child.type !== NodeTypes.TEXT || child.content !== ' ') {
- callArgs.push(child)
- }
- // mark dynamic text with flag so it gets patched inside a block
- if (child.type !== NodeTypes.TEXT) {
- callArgs.push(
- `${PatchFlags.TEXT} /* ${PatchFlagNames[PatchFlags.TEXT]} */`
- )
- }
- children[i] = {
- type: NodeTypes.TEXT_CALL,
- content: child,
- loc: child.loc,
- codegenNode: createCallExpression(
- context.helper(CREATE_TEXT),
- callArgs
- )
- }
+ if (
+ !hasText ||
+ // if this is a plain element with a single text child, leave it as-is
+ // since the runtime has dedicated fast path for this by directly
+ // setting textContent of the element.
+ (node.type === NodeTypes.ELEMENT &&
+ node.tagType === ElementTypes.ELEMENT &&
+ children.length === 1)
+ ) {
+ return
+ }
+
+ // pre-convert text nodes into createTextVNode(text) calls to avoid
+ // runtime normalization.
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i]
+ if (isText(child) || child.type === NodeTypes.COMPOUND_EXPRESSION) {
+ const callArgs: CallExpression['arguments'] = []
+ // createTextVNode defaults to single whitespace, so if it is a
+ // single space the code could be an empty call to save bytes.
+ if (child.type !== NodeTypes.TEXT || child.content !== ' ') {
+ callArgs.push(child)
+ }
+ // mark dynamic text with flag so it gets patched inside a block
+ if (child.type !== NodeTypes.TEXT) {
+ callArgs.push(
+ `${PatchFlags.TEXT} /* ${PatchFlagNames[PatchFlags.TEXT]} */`
+ )
+ }
+ children[i] = {
+ type: NodeTypes.TEXT_CALL,
+ content: child,
+ loc: child.loc,
+ codegenNode: createCallExpression(
+ context.helper(CREATE_TEXT),
+ callArgs
+ )
}
}
}