feat(v-on): cache handlers
This commit is contained in:
@@ -8,17 +8,14 @@ import {
|
||||
PlainElementNode,
|
||||
ComponentNode,
|
||||
TemplateNode,
|
||||
ElementNode
|
||||
ElementNode,
|
||||
PlainElementCodegenNode
|
||||
} from '../ast'
|
||||
import { TransformContext } from '../transform'
|
||||
import { WITH_DIRECTIVES } from '../runtimeHelpers'
|
||||
import { PatchFlags, isString, isSymbol } from '@vue/shared'
|
||||
import { isSlotOutlet, findProp } from '../utils'
|
||||
|
||||
function hasDynamicKeyOrRef(node: ElementNode) {
|
||||
return findProp(node, 'key', true) || findProp(node, 'ref', true)
|
||||
}
|
||||
|
||||
export function hoistStatic(root: RootNode, context: TransformContext) {
|
||||
walk(
|
||||
root.children,
|
||||
@@ -53,10 +50,11 @@ function walk(
|
||||
child.type === NodeTypes.ELEMENT &&
|
||||
child.tagType === ElementTypes.ELEMENT
|
||||
) {
|
||||
const hasBailoutProp = hasDynamicKeyOrRef(child) || hasCachedProps(child)
|
||||
if (
|
||||
!doNotHoistNode &&
|
||||
isStaticNode(child, resultCache) &&
|
||||
!hasDynamicKeyOrRef(child)
|
||||
!hasBailoutProp &&
|
||||
isStaticNode(child, resultCache)
|
||||
) {
|
||||
// whole tree is static
|
||||
child.codegenNode = context.hoist(child.codegenNode!)
|
||||
@@ -69,15 +67,11 @@ function walk(
|
||||
(!flag ||
|
||||
flag === PatchFlags.NEED_PATCH ||
|
||||
flag === PatchFlags.TEXT) &&
|
||||
!hasDynamicKeyOrRef(child)
|
||||
!hasBailoutProp
|
||||
) {
|
||||
let codegenNode = child.codegenNode as ElementCodegenNode
|
||||
if (codegenNode.callee === WITH_DIRECTIVES) {
|
||||
codegenNode = codegenNode.arguments[0]
|
||||
}
|
||||
const props = codegenNode.arguments[1]
|
||||
const props = getNodeProps(child)
|
||||
if (props && props !== `null`) {
|
||||
codegenNode.arguments[1] = context.hoist(props)
|
||||
getVNodeCall(child).arguments[1] = context.hoist(props)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,15 +91,6 @@ function walk(
|
||||
}
|
||||
}
|
||||
|
||||
function getPatchFlag(node: PlainElementNode): number | undefined {
|
||||
let codegenNode = node.codegenNode as ElementCodegenNode
|
||||
if (codegenNode.callee === WITH_DIRECTIVES) {
|
||||
codegenNode = codegenNode.arguments[0]
|
||||
}
|
||||
const flag = codegenNode.arguments[3]
|
||||
return flag ? parseInt(flag, 10) : undefined
|
||||
}
|
||||
|
||||
export function isStaticNode(
|
||||
node: TemplateChildNode | SimpleExpressionNode,
|
||||
resultCache: Map<TemplateChildNode, boolean> = new Map()
|
||||
@@ -157,3 +142,51 @@ export function isStaticNode(
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function hasDynamicKeyOrRef(node: ElementNode): boolean {
|
||||
return !!(findProp(node, 'key', true) || findProp(node, 'ref', true))
|
||||
}
|
||||
|
||||
function hasCachedProps(node: PlainElementNode): boolean {
|
||||
if (__BROWSER__) {
|
||||
return false
|
||||
}
|
||||
const props = getNodeProps(node)
|
||||
if (
|
||||
props &&
|
||||
props !== 'null' &&
|
||||
props.type === NodeTypes.JS_OBJECT_EXPRESSION
|
||||
) {
|
||||
const { properties } = props
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
if (properties[i].value.type === NodeTypes.JS_CACHE_EXPRESSION) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function getVNodeCall(node: PlainElementNode) {
|
||||
let codegenNode = node.codegenNode as ElementCodegenNode
|
||||
if (codegenNode.callee === WITH_DIRECTIVES) {
|
||||
codegenNode = codegenNode.arguments[0]
|
||||
}
|
||||
return codegenNode
|
||||
}
|
||||
|
||||
function getVNodeArgAt(
|
||||
node: PlainElementNode,
|
||||
index: number
|
||||
): PlainElementCodegenNode['arguments'][number] {
|
||||
return getVNodeCall(node).arguments[index]
|
||||
}
|
||||
|
||||
function getPatchFlag(node: PlainElementNode): number | undefined {
|
||||
const flag = getVNodeArgAt(node, 3) as string
|
||||
return flag ? parseInt(flag, 10) : undefined
|
||||
}
|
||||
|
||||
function getNodeProps(node: PlainElementNode) {
|
||||
return getVNodeArgAt(node, 1) as PlainElementCodegenNode['arguments'][1]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user