index.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <template>
  2. <uni-shadow-root class="vant-swipe-cell-index"><view class="van-swipe-cell" 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: [Number, String],
  45. value: '',
  46. },
  47. },
  48. mixins: [touch],
  49. data: {
  50. catchMove: false,
  51. },
  52. created() {
  53. this.offset = 0;
  54. ARRAY.push(this);
  55. },
  56. destroyed() {
  57. ARRAY = ARRAY.filter((item) => item !== this);
  58. },
  59. methods: {
  60. open(position) {
  61. const { leftWidth, rightWidth } = this.data;
  62. const offset = position === 'left' ? leftWidth : -rightWidth;
  63. this.swipeMove(offset);
  64. this.$emit('open', {
  65. position,
  66. name: this.data.name,
  67. });
  68. },
  69. close() {
  70. this.swipeMove(0);
  71. },
  72. swipeMove(offset = 0) {
  73. this.offset = range(offset, -this.data.rightWidth, this.data.leftWidth);
  74. const transform = `translate3d(${this.offset}px, 0, 0)`;
  75. const transition = this.dragging
  76. ? 'none'
  77. : 'transform .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
  78. this.setData({
  79. wrapperStyle: `
  80. -webkit-transform: ${transform};
  81. -webkit-transition: ${transition};
  82. transform: ${transform};
  83. transition: ${transition};
  84. `,
  85. });
  86. },
  87. swipeLeaveTransition() {
  88. const { leftWidth, rightWidth } = this.data;
  89. const { offset } = this;
  90. if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
  91. this.open('right');
  92. } else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
  93. this.open('left');
  94. } else {
  95. this.swipeMove(0);
  96. }
  97. this.setData({ catchMove: false });
  98. },
  99. startDrag(event) {
  100. if (this.data.disabled) {
  101. return;
  102. }
  103. this.startOffset = this.offset;
  104. this.touchStart(event);
  105. },
  106. noop() {},
  107. onDrag(event) {
  108. if (this.data.disabled) {
  109. return;
  110. }
  111. this.touchMove(event);
  112. if (this.direction !== 'horizontal') {
  113. return;
  114. }
  115. this.dragging = true;
  116. ARRAY.filter((item) => item !== this).forEach((item) => item.close());
  117. this.setData({ catchMove: true });
  118. this.swipeMove(this.startOffset + this.deltaX);
  119. },
  120. endDrag() {
  121. if (this.data.disabled) {
  122. return;
  123. }
  124. this.dragging = false;
  125. this.swipeLeaveTransition();
  126. },
  127. onClick(event) {
  128. const { key: position = 'outside' } = event.currentTarget.dataset;
  129. this.$emit('click', position);
  130. if (!this.offset) {
  131. return;
  132. }
  133. if (this.data.asyncClose) {
  134. this.$emit('close', {
  135. position,
  136. instance: this,
  137. name: this.data.name,
  138. });
  139. } else {
  140. this.swipeMove(0);
  141. }
  142. },
  143. },
  144. });
  145. export default global['__wxComponents']['vant/swipe-cell/index']
  146. </script>
  147. <style platform="mp-weixin">
  148. @import '../common/index.css';.van-swipe-cell{position:relative;overflow:hidden}.van-swipe-cell__left,.van-swipe-cell__right{position:absolute;top:0;height:100%}.van-swipe-cell__left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.van-swipe-cell__right{right:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}
  149. </style>