const n4 = t0()
_renderEffect(() => _setText(n4, _ctx1[0].value+_ctx0[0].value))
return n4
- }, null, null, n5)
+ }, null, n5)
_insert(n2, n5)
return n5
})
const n0 = _createFor(() => (_ctx.list), (_ctx0) => {
const n2 = t0()
return n2
- }, null, null, null, null, true)
+ }, null, null, null, true)
return n0
}"
`;
context: CodegenContext,
): CodeFragment[] {
const { vaporHelper } = context
- const {
- source,
- value,
- key,
- index,
- render,
- keyProp,
- once,
- id,
- memo,
- container,
- } = oper
+ const { source, value, key, index, render, keyProp, once, id, container } =
+ oper
let isDestructure = false
let rawValue: string | null = null
sourceExpr,
blockFn,
genCallback(keyProp),
- genCallback(memo),
container != null && `n${container}`,
false, // todo: hydrationNode
once && 'true',
value?: SimpleExpressionNode
key?: SimpleExpressionNode
index?: SimpleExpressionNode
- memo?: SimpleExpressionNode
}
export interface ForIRNode extends BaseIRNode, IRFor {
IRNodeTypes,
type VaporDirectiveNode,
} from '../ir'
-import { findDir, findProp, propToExpression } from '../utils'
+import { findProp, propToExpression } from '../utils'
import { newBlock, wrapTemplate } from './utils'
export const transformVFor: NodeTransform = createStructuralDirectiveTransform(
const { source, value, key, index } = parseResult
const keyProp = findProp(node, 'key')
- const memo = findDir(node, 'memo')
const keyProperty = keyProp && propToExpression(keyProp)
context.node = node = wrapTemplate(node, ['for'])
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
keyProp: keyProperty,
render,
once: context.inVOnce,
- memo: memo && memo.exp,
container,
})
}
import { componentKey } from './component'
import type { DynamicSlot } from './componentSlots'
import { renderEffect } from './renderEffect'
-import { withMemo } from './memo'
interface ForBlock extends Fragment {
scope: EffectScope
index: ShallowRef<number | undefined>,
]
key: any
- memo: any[] | undefined
}
type Source = any[] | Record<any, any> | number | Set<any> | Map<any, any>
src: () => Source,
renderItem: (block: ForBlock['state']) => Block,
getKey?: (item: any, key: any, index?: number) => any,
- getMemo?: (item: any, key: any, index?: number) => any[],
container?: ParentNode,
hydrationNode?: Node,
once?: boolean,
warn('createFor() can only be used inside setup()')
}
- const update = getMemo ? updateWithMemo : updateWithoutMemo
once ? renderList() : renderEffect(renderList)
return ref
scope,
state,
key: getKey && getKey(item, key, index),
- memo: getMemo && getMemo(item, key, index),
[fragmentKey]: true,
})
- block.nodes = scope.run(() => {
- if (getMemo) {
- return withMemo(
- () =>
- getMemo(
- block.state[0].value,
- block.state[1].value,
- block.state[2].value,
- ),
- () => renderItem(state),
- )
- }
- return renderItem(state)
- })!
+ block.nodes = scope.run(() => renderItem(state))!
if (parent) insert(block.nodes, parent, anchor)
}
}
- function updateWithMemo(
- block: ForBlock,
- newItem: any,
- newKey = block.state[1].value,
- newIndex = block.state[2].value,
- ) {
- const [, key, index] = block.state
- let needsUpdate = newKey !== key.value || newIndex !== index.value
- if (!needsUpdate) {
- const oldMemo = block.memo!
- const newMemo = (block.memo = getMemo!(newItem, newKey, newIndex))
- for (let i = 0; i < newMemo.length; i++) {
- if ((needsUpdate = newMemo[i] !== oldMemo[i])) {
- break
- }
- }
- }
-
- if (needsUpdate) updateState(block, newItem, newKey, newIndex)
- }
-
- function updateWithoutMemo(
+ function update(
block: ForBlock,
newItem: any,
newKey = block.state[1].value,
+++ /dev/null
-export const memoStack: Array<() => any[]> = []
-
-export function withMemo<T>(memo: () => any[], callback: () => T): T {
- memoStack.push(memo)
- const res = callback()
- memoStack.pop()
- return res
-}
queuePostFlushCb,
} from './scheduler'
import { VaporErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
-import { memoStack } from './memo'
export function renderEffect(cb: () => void): void {
const instance = getCurrentInstance()
job.id = instance.uid
}
- let memos: (() => any[])[] | undefined
- let memoCaches: any[][]
- if (memoStack.length) {
- memos = Array.from(memoStack)
- memoCaches = memos.map(memo => memo())
- }
-
const effect = new ReactiveEffect(() =>
callWithAsyncErrorHandling(cb, instance, VaporErrorCodes.RENDER_FUNCTION),
)
return
}
- if (memos) {
- let dirty: boolean | undefined
- for (let i = 0; i < memos.length; i++) {
- const memo = memos[i]
- const cache = memoCaches[i]
- const value = memo()
-
- for (let j = 0; j < Math.max(value.length, cache.length); j++) {
- if (value[j] !== cache[j]) {
- dirty = true
- break
- }
- }
-
- memoCaches[i] = value
- }
-
- if (!dirty) {
- return
- }
- }
-
const reset = instance && setCurrentInstance(instance)
if (instance && instance.isMounted && !instance.isUpdating) {