index.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { VantComponent } from '../common/component';
  2. import { touch } from '../mixins/touch';
  3. import { range } from '../common/utils';
  4. const THRESHOLD = 0.3;
  5. let ARRAY = [];
  6. VantComponent({
  7. props: {
  8. disabled: Boolean,
  9. leftWidth: {
  10. type: Number,
  11. value: 0,
  12. observer(leftWidth = 0) {
  13. if (this.offset > 0) {
  14. this.swipeMove(leftWidth);
  15. }
  16. },
  17. },
  18. rightWidth: {
  19. type: Number,
  20. value: 0,
  21. observer(rightWidth = 0) {
  22. if (this.offset < 0) {
  23. this.swipeMove(-rightWidth);
  24. }
  25. },
  26. },
  27. asyncClose: Boolean,
  28. name: {
  29. type: null,
  30. value: '',
  31. },
  32. },
  33. mixins: [touch],
  34. data: {
  35. catchMove: false,
  36. wrapperStyle: '',
  37. },
  38. created() {
  39. this.offset = 0;
  40. ARRAY.push(this);
  41. },
  42. destroyed() {
  43. ARRAY = ARRAY.filter((item) => item !== this);
  44. },
  45. methods: {
  46. open(position) {
  47. const { leftWidth, rightWidth } = this.data;
  48. const offset = position === 'left' ? leftWidth : -rightWidth;
  49. this.swipeMove(offset);
  50. this.$emit('open', {
  51. position,
  52. name: this.data.name,
  53. });
  54. },
  55. close() {
  56. this.swipeMove(0);
  57. },
  58. swipeMove(offset = 0) {
  59. this.offset = range(offset, -this.data.rightWidth, this.data.leftWidth);
  60. const transform = `translate3d(${this.offset}px, 0, 0)`;
  61. const transition = this.dragging
  62. ? 'none'
  63. : 'transform .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
  64. this.setData({
  65. wrapperStyle: `
  66. -webkit-transform: ${transform};
  67. -webkit-transition: ${transition};
  68. transform: ${transform};
  69. transition: ${transition};
  70. `,
  71. });
  72. },
  73. swipeLeaveTransition() {
  74. const { leftWidth, rightWidth } = this.data;
  75. const { offset } = this;
  76. if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
  77. this.open('right');
  78. }
  79. else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
  80. this.open('left');
  81. }
  82. else {
  83. this.swipeMove(0);
  84. }
  85. this.setData({ catchMove: false });
  86. },
  87. startDrag(event) {
  88. if (this.data.disabled) {
  89. return;
  90. }
  91. this.startOffset = this.offset;
  92. this.touchStart(event);
  93. },
  94. noop() { },
  95. onDrag(event) {
  96. if (this.data.disabled) {
  97. return;
  98. }
  99. this.touchMove(event);
  100. if (this.direction !== 'horizontal') {
  101. return;
  102. }
  103. this.dragging = true;
  104. ARRAY.filter((item) => item !== this && item.offset !== 0).forEach((item) => item.close());
  105. this.setData({ catchMove: true });
  106. this.swipeMove(this.startOffset + this.deltaX);
  107. },
  108. endDrag() {
  109. if (this.data.disabled) {
  110. return;
  111. }
  112. this.dragging = false;
  113. this.swipeLeaveTransition();
  114. },
  115. onClick(event) {
  116. const { key: position = 'outside' } = event.currentTarget.dataset;
  117. this.$emit('click', position);
  118. if (!this.offset) {
  119. return;
  120. }
  121. if (this.data.asyncClose) {
  122. this.$emit('close', {
  123. position,
  124. instance: this,
  125. name: this.data.name,
  126. });
  127. }
  128. else {
  129. this.swipeMove(0);
  130. }
  131. },
  132. },
  133. });