Transition.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import {
  2. NodeTransform,
  3. NodeTypes,
  4. ElementTypes,
  5. ComponentNode,
  6. IfBranchNode
  7. } from '@vue/compiler-core'
  8. import { TRANSITION } from '../runtimeHelpers'
  9. import { createDOMCompilerError, DOMErrorCodes } from '../errors'
  10. export const transformTransition: NodeTransform = (node, context) => {
  11. if (
  12. node.type === NodeTypes.ELEMENT &&
  13. node.tagType === ElementTypes.COMPONENT
  14. ) {
  15. const component = context.isBuiltInComponent(node.tag)
  16. if (component === TRANSITION) {
  17. return () => {
  18. if (!node.children.length) {
  19. return
  20. }
  21. // warn multiple transition children
  22. if (hasMultipleChildren(node)) {
  23. context.onError(
  24. createDOMCompilerError(
  25. DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN,
  26. {
  27. start: node.children[0].loc.start,
  28. end: node.children[node.children.length - 1].loc.end,
  29. source: ''
  30. }
  31. )
  32. )
  33. }
  34. // check if it's s single child w/ v-show
  35. // if yes, inject "persisted: true" to the transition props
  36. const child = node.children[0]
  37. if (child.type === NodeTypes.ELEMENT) {
  38. for (const p of child.props) {
  39. if (p.type === NodeTypes.DIRECTIVE && p.name === 'show') {
  40. node.props.push({
  41. type: NodeTypes.ATTRIBUTE,
  42. name: 'persisted',
  43. value: undefined,
  44. loc: node.loc
  45. })
  46. }
  47. }
  48. }
  49. }
  50. }
  51. }
  52. }
  53. function hasMultipleChildren(node: ComponentNode | IfBranchNode): boolean {
  54. // #1352 filter out potential comment nodes.
  55. const children = (node.children = node.children.filter(
  56. c =>
  57. c.type !== NodeTypes.COMMENT &&
  58. !(c.type === NodeTypes.TEXT && !c.content.trim())
  59. ))
  60. const child = children[0]
  61. return (
  62. children.length !== 1 ||
  63. child.type === NodeTypes.FOR ||
  64. (child.type === NodeTypes.IF && child.branches.some(hasMultipleChildren))
  65. )
  66. }