vMemo.ts 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import { NodeTransform } from '../transform'
  2. import { findDir } from '../utils'
  3. import {
  4. convertToBlock,
  5. createCallExpression,
  6. createFunctionExpression,
  7. ElementTypes,
  8. MemoExpression,
  9. NodeTypes,
  10. PlainElementNode
  11. } from '../ast'
  12. import { WITH_MEMO } from '../runtimeHelpers'
  13. const seen = new WeakSet()
  14. export const transformMemo: NodeTransform = (node, context) => {
  15. if (node.type === NodeTypes.ELEMENT) {
  16. const dir = findDir(node, 'memo')
  17. if (!dir || seen.has(node)) {
  18. return
  19. }
  20. seen.add(node)
  21. return () => {
  22. const codegenNode =
  23. node.codegenNode ||
  24. (context.currentNode as PlainElementNode).codegenNode
  25. if (codegenNode && codegenNode.type === NodeTypes.VNODE_CALL) {
  26. // non-component sub tree should be turned into a block
  27. if (node.tagType !== ElementTypes.COMPONENT) {
  28. convertToBlock(codegenNode, context)
  29. }
  30. node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
  31. dir.exp!,
  32. createFunctionExpression(undefined, codegenNode),
  33. `_cache`,
  34. String(context.cached++)
  35. ]) as MemoExpression
  36. }
  37. }
  38. }
  39. }