fix(compiler-core): should pre-convert text nodes in all non-element cases
This commit is contained in:
parent
57bbbb227c
commit
42f3f9e832
@ -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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user