feat(v-on): cache handlers

This commit is contained in:
Evan You
2019-10-18 21:51:34 -04:00
parent 39ea67a2d2
commit 58593c4714
19 changed files with 529 additions and 243 deletions

View File

@@ -21,13 +21,14 @@ import {
ElementCodegenNode,
SlotOutletCodegenNode,
ComponentCodegenNode,
ExpressionNode
ExpressionNode,
IfBranchNode
} from './ast'
import { parse } from 'acorn'
import { walk } from 'estree-walker'
import { TransformContext } from './transform'
import { OPEN_BLOCK, MERGE_PROPS, RENDER_SLOT } from './runtimeHelpers'
import { isString, isFunction } from '@vue/shared'
import { isString, isFunction, isObject } from '@vue/shared'
// cache node requires
// lazy require dependencies so that they don't end up in rollup's dep graph
@@ -250,3 +251,51 @@ export function toValidAssetId(
export function isEmptyExpression(node: ExpressionNode) {
return node.type === NodeTypes.SIMPLE_EXPRESSION && !node.content.trim()
}
// Check if a node contains expressions that reference current context scope ids
export function hasScopeRef(
node: TemplateChildNode | IfBranchNode | ExpressionNode | undefined,
ids: TransformContext['identifiers']
): boolean {
if (!node || Object.keys(ids).length === 0) {
return false
}
switch (node.type) {
case NodeTypes.ELEMENT:
for (let i = 0; i < node.props.length; i++) {
const p = node.props[i]
if (
p.type === NodeTypes.DIRECTIVE &&
(hasScopeRef(p.arg, ids) || hasScopeRef(p.exp, ids))
) {
return true
}
}
return node.children.some(c => hasScopeRef(c, ids))
case NodeTypes.FOR:
if (hasScopeRef(node.source, ids)) {
return true
}
return node.children.some(c => hasScopeRef(c, ids))
case NodeTypes.IF:
return node.branches.some(b => hasScopeRef(b, ids))
case NodeTypes.IF_BRANCH:
if (hasScopeRef(node.condition, ids)) {
return true
}
return node.children.some(c => hasScopeRef(c, ids))
case NodeTypes.SIMPLE_EXPRESSION:
return (
!node.isStatic &&
isSimpleIdentifier(node.content) &&
!!ids[node.content]
)
case NodeTypes.COMPOUND_EXPRESSION:
return node.children.some(c => isObject(c) && hasScopeRef(c, ids))
case NodeTypes.INTERPOLATION:
return hasScopeRef(node.content, ids)
default:
// TextNode or CommentNode
return false
}
}