index.js 3.7 KB

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