fix(compiler-core): should pre-convert text nodes in all non-element cases

This commit is contained in:
Evan You 2019-12-02 15:17:00 -05:00
parent 57bbbb227c
commit 42f3f9e832

View File

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