CREATE_STATIC,
CREATE_TEXT,
CREATE_VNODE,
+ HOIST_LAZY,
OPEN_BLOCK,
POP_SCOPE_ID,
PUSH_SCOPE_ID,
if (genScopeId && ast.hoists.length) {
ast.helpers.add(PUSH_SCOPE_ID)
ast.helpers.add(POP_SCOPE_ID)
+ ast.helpers.add(HOIST_LAZY)
}
// generate import statements for helpers
if (exp) {
const needScopeIdWrapper = genScopeId && exp.type === NodeTypes.VNODE_CALL
push(
- `const _hoisted_${i + 1} = ${
- needScopeIdWrapper ? `${PURE_ANNOTATION} _withScopeId(() => ` : ``
+ `const _hoisted_${i + 1} = ${PURE_ANNOTATION} ${helper(HOIST_LAZY)}(() => (${
+ needScopeIdWrapper ? `_withScopeId(() => ` : ``
}`,
)
genNode(exp, context)
if (needScopeIdWrapper) {
push(`)`)
}
+ push('))')
newline()
}
}
export const CREATE_VNODE = Symbol(__DEV__ ? `createVNode` : ``)
export const CREATE_ELEMENT_VNODE = Symbol(__DEV__ ? `createElementVNode` : ``)
export const CREATE_COMMENT = Symbol(__DEV__ ? `createCommentVNode` : ``)
+export const HOIST_LAZY = Symbol(__DEV__ ? `hoistLazy` : ``)
export const CREATE_TEXT = Symbol(__DEV__ ? `createTextVNode` : ``)
export const CREATE_STATIC = Symbol(__DEV__ ? `createStaticVNode` : ``)
export const RESOLVE_COMPONENT = Symbol(__DEV__ ? `resolveComponent` : ``)
[POP_SCOPE_ID]: `popScopeId`,
[WITH_CTX]: `withCtx`,
[UNREF]: `unref`,
+ [HOIST_LAZY]: `hoistLazy`,
[IS_REF]: `isRef`,
[WITH_MEMO]: `withMemo`,
[IS_MEMO_SAME]: `isMemoSame`,
if (isString(exp)) exp = createSimpleExpression(exp)
context.hoists.push(exp)
const identifier = createSimpleExpression(
- `_hoisted_${context.hoists.length}`,
+ `_hoisted_${context.hoists.length}()`,
false,
exp.loc,
ConstantTypes.CAN_HOIST,
import { isSlotOutlet } from '../utils'
import {
GUARD_REACTIVE_PROPS,
+ HOIST_LAZY,
NORMALIZE_CLASS,
NORMALIZE_PROPS,
NORMALIZE_STYLE,
: getConstantType(child, context)
if (constantType > ConstantTypes.NOT_CONSTANT) {
if (constantType >= ConstantTypes.CAN_HOIST) {
+ context.helper(HOIST_LAZY)
;(child.codegenNode as VNodeCall).patchFlag =
PatchFlags.HOISTED + (__DEV__ ? ` /* HOISTED */` : ``)
child.codegenNode = context.hoist(child.codegenNode!)
// For raw render function users
export { h } from './h'
// Advanced render function utilities
-export { createVNode, cloneVNode, mergeProps, isVNode } from './vnode'
+export {
+ createVNode,
+ cloneVNode,
+ mergeProps,
+ isVNode,
+ hoistLazy,
+} from './vnode'
// VNode types
export { Fragment, Text, Comment, Static, type VNodeRef } from './vnode'
// Built-in components
prevVNode,
])
}
+
+export function hoistLazy<T>(fn: () => T): () => T {
+ let cache: T | undefined
+ return (): T => {
+ if (!cache) {
+ cache = fn()
+ }
+ return cache
+ }
+}