feat(compiler-core): do not generate TEXT flag if child is constant
This commit is contained in:
@@ -15,9 +15,8 @@ import { APPLY_DIRECTIVES } from '../runtimeHelpers'
|
||||
import { PatchFlags, isString, isSymbol } from '@vue/shared'
|
||||
import { isSlotOutlet, findProp } from '../utils'
|
||||
|
||||
function hasDynamicKey(node: ElementNode) {
|
||||
const keyProp = findProp(node, 'key')
|
||||
return keyProp && keyProp.type === NodeTypes.DIRECTIVE
|
||||
function hasDynamicKeyOrRef(node: ElementNode) {
|
||||
return findProp(node, 'key', true) || findProp(node, 'ref', true)
|
||||
}
|
||||
|
||||
export function hoistStatic(root: RootNode, context: TransformContext) {
|
||||
@@ -57,7 +56,7 @@ function walk(
|
||||
if (
|
||||
!doNotHoistNode &&
|
||||
isStaticNode(child, resultCache) &&
|
||||
!hasDynamicKey(child)
|
||||
!hasDynamicKeyOrRef(child)
|
||||
) {
|
||||
// whole tree is static
|
||||
child.codegenNode = context.hoist(child.codegenNode!)
|
||||
@@ -70,7 +69,7 @@ function walk(
|
||||
(!flag ||
|
||||
flag === PatchFlags.NEED_PATCH ||
|
||||
flag === PatchFlags.TEXT) &&
|
||||
!hasDynamicKey(child)
|
||||
!hasDynamicKeyOrRef(child)
|
||||
) {
|
||||
let codegenNode = child.codegenNode as ElementCodegenNode
|
||||
if (codegenNode.callee === APPLY_DIRECTIVES) {
|
||||
@@ -107,9 +106,9 @@ function getPatchFlag(node: PlainElementNode): number | undefined {
|
||||
return flag ? parseInt(flag, 10) : undefined
|
||||
}
|
||||
|
||||
function isStaticNode(
|
||||
export function isStaticNode(
|
||||
node: TemplateChildNode | SimpleExpressionNode,
|
||||
resultCache: Map<TemplateChildNode, boolean>
|
||||
resultCache: Map<TemplateChildNode, boolean> = new Map()
|
||||
): boolean {
|
||||
switch (node.type) {
|
||||
case NodeTypes.ELEMENT:
|
||||
@@ -121,7 +120,7 @@ function isStaticNode(
|
||||
return cached
|
||||
}
|
||||
const flag = getPatchFlag(node)
|
||||
if (!flag || flag === PatchFlags.TEXT) {
|
||||
if (!flag) {
|
||||
// element self is static. check its children.
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
if (!isStaticNode(node.children[i], resultCache)) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
} from '../runtimeHelpers'
|
||||
import { getInnerRange, isVSlot, toValidAssetId } from '../utils'
|
||||
import { buildSlots } from './vSlot'
|
||||
import { isStaticNode } from './hoistStatic'
|
||||
|
||||
// some directive transforms (e.g. v-model) may return a symbol for runtime
|
||||
// import, which should be used instead of a resolveDirective call.
|
||||
@@ -93,10 +94,11 @@ export const transformElement: NodeTransform = (node, context) => {
|
||||
} else if (node.children.length === 1) {
|
||||
const child = node.children[0]
|
||||
const type = child.type
|
||||
// check for dynamic text children
|
||||
const hasDynamicTextChild =
|
||||
type === NodeTypes.INTERPOLATION ||
|
||||
type === NodeTypes.COMPOUND_EXPRESSION
|
||||
if (hasDynamicTextChild) {
|
||||
if (hasDynamicTextChild && !isStaticNode(child)) {
|
||||
patchFlag |= PatchFlags.TEXT
|
||||
}
|
||||
// pass directly if the only child is a text node
|
||||
|
||||
Reference in New Issue
Block a user