index.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <uni-shadow-root class="vant-swipe-cell-index"><view class="van-swipe-cell custom-class" data-key="cell" @click.stop.prevent="onClick" @touchstart="startDrag" @touchmove.stop.prevent="_$self[(catchMove ? 'noop' : '')||'_$noop']($event)" @touchmove.capture="onDrag" @touchend="endDrag" @touchcancel="endDrag">
  3. <view :style="wrapperStyle">
  4. <view v-if="leftWidth" class="van-swipe-cell__left" data-key="left" @click.stop.prevent="onClick">
  5. <slot name="left"></slot>
  6. </view>
  7. <slot></slot>
  8. <view v-if="rightWidth" class="van-swipe-cell__right" data-key="right" @click.stop.prevent="onClick">
  9. <slot name="right"></slot>
  10. </view>
  11. </view>
  12. </view></uni-shadow-root>
  13. </template>
  14. <script>
  15. global['__wxRoute'] = 'vant/swipe-cell/index'
  16. import { VantComponent } from '../common/component';
  17. import { touch } from '../mixins/touch';
  18. import { range } from '../common/utils';
  19. const THRESHOLD = 0.3;
  20. let ARRAY = [];
  21. VantComponent({
  22. props: {
  23. disabled: Boolean,
  24. leftWidth: {
  25. type: Number,
  26. value: 0,
  27. observer(leftWidth = 0) {
  28. if (this.offset > 0) {
  29. this.swipeMove(leftWidth);
  30. }
  31. },
  32. },
  33. rightWidth: {
  34. type: Number,
  35. value: 0,
  36. observer(rightWidth = 0) {
  37. if (this.offset < 0) {
  38. this.swipeMove(-rightWidth);
  39. }
  40. },
  41. },
  42. asyncClose: Boolean,
  43. name: {
  44. type: null,
  45. value: '',
  46. },
  47. },
  48. mixins: [touch],
  49. data: {
  50. catchMove: false,
  51. wrapperStyle: '',
  52. },
  53. created() {
  54. this.offset = 0;
  55. ARRAY.push(this);
  56. },
  57. destroyed() {
  58. ARRAY = ARRAY.filter((item) => item !== this);
  59. },
  60. methods: {
  61. open(position) {
  62. const { leftWidth, rightWidth } = this.data;
  63. const offset = position === 'left' ? leftWidth : -rightWidth;
  64. this.swipeMove(offset);
  65. this.$emit('open', {
  66. position,
  67. name: this.data.name,
  68. });
  69. },
  70. close() {
  71. this.swipeMove(0);
  72. },
  73. swipeMove(offset = 0) {
  74. this.offset = range(offset, -this.data.rightWidth, this.data.leftWidth);
  75. const transform = `translate3d(${this.offset}px, 0, 0)`;
  76. const transition = this.dragging
  77. ? 'none'
  78. : 'transform .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
  79. this.setData({
  80. wrapperStyle: `
  81. -webkit-transform: ${transform};
  82. -webkit-transition: ${transition};
  83. transform: ${transform};
  84. transition: ${transition};
  85. `,
  86. });
  87. },
  88. swipeLeaveTransition() {
  89. const { leftWidth, rightWidth } = this.data;
  90. const { offset } = this;
  91. if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
  92. this.open('right');
  93. }
  94. else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
  95. this.open('left');
  96. }
  97. else {
  98. this.swipeMove(0);
  99. }
  100. this.setData({ catchMove: false });
  101. },
  102. startDrag(event) {
  103. if (this.data.disabled) {
  104. return;
  105. }
  106. this.startOffset = this.offset;
  107. this.touchStart(event);
  108. },
  109. noop() { },
  110. onDrag(event) {
  111. if (this.data.disabled) {
  112. return;
  113. }
  114. this.touchMove(event);
  115. if (this.direction !== 'horizontal') {
  116. return;
  117. }
  118. this.dragging = true;
  119. ARRAY.filter((item) => item !== this && item.offset !== 0).forEach((item) => item.close());
  120. this.setData({ catchMove: true });
  121. this.swipeMove(this.startOffset + this.deltaX);
  122. },
  123. endDrag() {
  124. if (this.data.disabled) {
  125. return;
  126. }
  127. this.dragging = false;
  128. this.swipeLeaveTransition();
  129. },
  130. onClick(event) {
  131. const { key: position = 'outside' } = event.currentTarget.dataset;
  132. this.$emit('click', position);
  133. if (!this.offset) {
  134. return;
  135. }
  136. if (this.data.asyncClose) {
  137. this.$emit('close', {
  138. position,
  139. instance: this,
  140. name: this.data.name,
  141. });
  142. }
  143. else {
  144. this.swipeMove(0);
  145. }
  146. },
  147. },
  148. });
  149. export default global['__wxComponents']['vant/swipe-cell/index']
  150. </script>
  151. <style platform="mp-weixin">
  152. @import '../common/index.css';.van-swipe-cell{overflow:hidden;position:relative}.van-swipe-cell__left,.van-swipe-cell__right{height:100%;position:absolute;top:0}.van-swipe-cell__left{left:0;transform:translate3d(-100%,0,0)}.van-swipe-cell__right{right:0;transform:translate3d(100%,0,0)}
  153. </style>