transition.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // @ts-nocheck
  2. import { requestAnimationFrame } from '../common/utils';
  3. import { isObj } from '../common/validator';
  4. const getClassNames = (name) => ({
  5. enter: `van-${name}-enter van-${name}-enter-active enter-class enter-active-class`,
  6. 'enter-to': `van-${name}-enter-to van-${name}-enter-active enter-to-class enter-active-class`,
  7. leave: `van-${name}-leave van-${name}-leave-active leave-class leave-active-class`,
  8. 'leave-to': `van-${name}-leave-to van-${name}-leave-active leave-to-class leave-active-class`,
  9. });
  10. export function transition(showDefaultValue) {
  11. return Behavior({
  12. properties: {
  13. customStyle: String,
  14. // @ts-ignore
  15. show: {
  16. type: Boolean,
  17. value: showDefaultValue,
  18. observer: 'observeShow',
  19. },
  20. // @ts-ignore
  21. duration: {
  22. type: null,
  23. value: 300,
  24. observer: 'observeDuration',
  25. },
  26. name: {
  27. type: String,
  28. value: 'fade',
  29. },
  30. },
  31. data: {
  32. type: '',
  33. inited: false,
  34. display: false,
  35. },
  36. ready() {
  37. if (this.data.show === true) {
  38. this.observeShow(true, false);
  39. }
  40. },
  41. methods: {
  42. observeShow(value, old) {
  43. if (value === old) {
  44. return;
  45. }
  46. value ? this.enter() : this.leave();
  47. },
  48. enter() {
  49. const { duration, name } = this.data;
  50. const classNames = getClassNames(name);
  51. const currentDuration = isObj(duration) ? duration.enter : duration;
  52. if (this.status === 'enter') {
  53. return;
  54. }
  55. this.status = 'enter';
  56. this.$emit('before-enter');
  57. requestAnimationFrame(() => {
  58. if (this.status !== 'enter') {
  59. return;
  60. }
  61. this.$emit('enter');
  62. this.setData({
  63. inited: true,
  64. display: true,
  65. classes: classNames.enter,
  66. currentDuration,
  67. });
  68. requestAnimationFrame(() => {
  69. if (this.status !== 'enter') {
  70. return;
  71. }
  72. this.transitionEnded = false;
  73. this.setData({ classes: classNames['enter-to'] });
  74. });
  75. });
  76. },
  77. leave() {
  78. if (!this.data.display) {
  79. return;
  80. }
  81. const { duration, name } = this.data;
  82. const classNames = getClassNames(name);
  83. const currentDuration = isObj(duration) ? duration.leave : duration;
  84. this.status = 'leave';
  85. this.$emit('before-leave');
  86. requestAnimationFrame(() => {
  87. if (this.status !== 'leave') {
  88. return;
  89. }
  90. this.$emit('leave');
  91. this.setData({
  92. classes: classNames.leave,
  93. currentDuration,
  94. });
  95. requestAnimationFrame(() => {
  96. if (this.status !== 'leave') {
  97. return;
  98. }
  99. this.transitionEnded = false;
  100. setTimeout(() => this.onTransitionEnd(), currentDuration);
  101. this.setData({ classes: classNames['leave-to'] });
  102. });
  103. });
  104. },
  105. onTransitionEnd() {
  106. if (this.transitionEnded) {
  107. return;
  108. }
  109. this.transitionEnded = true;
  110. this.$emit(`after-${this.status}`);
  111. const { show, display } = this.data;
  112. if (!show && display) {
  113. this.setData({ display: false });
  114. }
  115. },
  116. },
  117. });
  118. }