index.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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: [Number, String],
  30. value: '',
  31. },
  32. },
  33. mixins: [touch],
  34. data: {
  35. catchMove: false,
  36. },
  37. created() {
  38. this.offset = 0;
  39. ARRAY.push(this);
  40. },
  41. destroyed() {
  42. ARRAY = ARRAY.filter((item) => item !== this);
  43. },
  44. methods: {
  45. open(position) {
  46. const { leftWidth, rightWidth } = this.data;
  47. const offset = position === 'left' ? leftWidth : -rightWidth;
  48. this.swipeMove(offset);
  49. this.$emit('open', {
  50. position,
  51. name: this.data.name,
  52. });
  53. },
  54. close() {
  55. this.swipeMove(0);
  56. },
  57. swipeMove(offset = 0) {
  58. this.offset = range(offset, -this.data.rightWidth, this.data.leftWidth);
  59. const transform = `translate3d(${this.offset}px, 0, 0)`;
  60. const transition = this.dragging
  61. ? 'none'
  62. : 'transform .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
  63. this.setData({
  64. wrapperStyle: `
  65. -webkit-transform: ${transform};
  66. -webkit-transition: ${transition};
  67. transform: ${transform};
  68. transition: ${transition};
  69. `,
  70. });
  71. },
  72. swipeLeaveTransition() {
  73. const { leftWidth, rightWidth } = this.data;
  74. const { offset } = this;
  75. if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
  76. this.open('right');
  77. } else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
  78. this.open('left');
  79. } else {
  80. this.swipeMove(0);
  81. }
  82. this.setData({ catchMove: false });
  83. },
  84. startDrag(event) {
  85. if (this.data.disabled) {
  86. return;
  87. }
  88. this.startOffset = this.offset;
  89. this.touchStart(event);
  90. },
  91. noop() {},
  92. onDrag(event) {
  93. if (this.data.disabled) {
  94. return;
  95. }
  96. this.touchMove(event);
  97. if (this.direction !== 'horizontal') {
  98. return;
  99. }
  100. this.dragging = true;
  101. ARRAY.filter((item) => item !== this).forEach((item) => item.close());
  102. this.setData({ catchMove: true });
  103. this.swipeMove(this.startOffset + this.deltaX);
  104. },
  105. endDrag() {
  106. if (this.data.disabled) {
  107. return;
  108. }
  109. this.dragging = false;
  110. this.swipeLeaveTransition();
  111. },
  112. onClick(event) {
  113. const { key: position = 'outside' } = event.currentTarget.dataset;
  114. this.$emit('click', position);
  115. if (!this.offset) {
  116. return;
  117. }
  118. if (this.data.asyncClose) {
  119. this.$emit('close', {
  120. position,
  121. instance: this,
  122. name: this.data.name,
  123. });
  124. } else {
  125. this.swipeMove(0);
  126. }
  127. },
  128. },
  129. });