index.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. }
  78. else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
  79. this.open('left');
  80. }
  81. else {
  82. this.swipeMove(0);
  83. }
  84. this.setData({ catchMove: false });
  85. },
  86. startDrag(event) {
  87. if (this.data.disabled) {
  88. return;
  89. }
  90. this.startOffset = this.offset;
  91. this.touchStart(event);
  92. },
  93. noop() { },
  94. onDrag(event) {
  95. if (this.data.disabled) {
  96. return;
  97. }
  98. this.touchMove(event);
  99. if (this.direction !== 'horizontal') {
  100. return;
  101. }
  102. this.dragging = true;
  103. ARRAY.filter(item => item !== this).forEach(item => item.close());
  104. this.setData({ catchMove: true });
  105. this.swipeMove(this.startOffset + this.deltaX);
  106. },
  107. endDrag() {
  108. if (this.data.disabled) {
  109. return;
  110. }
  111. this.dragging = false;
  112. this.swipeLeaveTransition();
  113. },
  114. onClick(event) {
  115. const { key: position = 'outside' } = event.currentTarget.dataset;
  116. this.$emit('click', position);
  117. if (!this.offset) {
  118. return;
  119. }
  120. if (this.data.asyncClose) {
  121. this.$emit('close', {
  122. position,
  123. instance: this,
  124. name: this.data.name
  125. });
  126. }
  127. else {
  128. this.swipeMove(0);
  129. }
  130. }
  131. }
  132. });