SwipeAction.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <template>
  2. <view class="slide">
  3. <view class="slide-left" :style="'position: relative;left:' + left + 'rpx'" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
  4. <slot></slot>
  5. </view>
  6. <view class="slide-right">
  7. <view
  8. class="btn-item"
  9. v-for="(item, index) in btnList"
  10. :key="index"
  11. :style="'width:' + item.width + ';height:' + height + 'rpx;background-color:' + item.bgColor + ';color:' + item.color + ';font-size:' + item.fontSize"
  12. @click.stop="clickItem(item)"
  13. >
  14. {{ item.name }}
  15. </view>
  16. </view>
  17. </view>
  18. </template>
  19. <script>
  20. export default {
  21. props: {
  22. //操作按钮数组
  23. btnList: {
  24. type: Array,
  25. default: () => {
  26. return [
  27. {
  28. id: "1",
  29. name: "删除",
  30. width: "100rpx",
  31. bgColor: "#ed656d",
  32. color: "#FFFFFF",
  33. fontSize: "28rpx",
  34. },
  35. ];
  36. },
  37. },
  38. //当前列索引
  39. index: {
  40. type: Number,
  41. require: true,
  42. default: 0,
  43. },
  44. //是否禁用
  45. disable: {
  46. type: Boolean,
  47. default: false,
  48. },
  49. pIndex: {
  50. type: String || Number,
  51. default: 0,
  52. },
  53. },
  54. data() {
  55. return {
  56. x: 0,
  57. left: 0,
  58. operation: 0,
  59. height: 0,
  60. screenWidth: 0,
  61. };
  62. },
  63. mounted() {
  64. this.$nextTick((res) => {
  65. const systemInfo = uni.getSystemInfoSync();
  66. this.screenWidth = systemInfo.screenWidth;
  67. this.getBtnWidth();
  68. this.getListHeight();
  69. });
  70. },
  71. methods: {
  72. clickItem(e) {
  73. this.$emit("clickItem", {
  74. index: this.index,
  75. id: e.id,
  76. pIndex: this.pIndex,
  77. });
  78. },
  79. //重置方法
  80. reset() {
  81. this.left = 0;
  82. },
  83. getBtnWidth() {
  84. let view = uni.createSelectorQuery().in(this).select(".slide-right");
  85. view
  86. .boundingClientRect((rect) => {
  87. this.operation = this.px2rpx(rect.width, this.screenWidth);
  88. })
  89. .exec();
  90. },
  91. getListHeight() {
  92. let view = uni.createSelectorQuery().in(this).select(".slide-left");
  93. view
  94. .boundingClientRect((rect) => {
  95. this.height = this.px2rpx(rect.height, this.screenWidth);
  96. })
  97. .exec();
  98. },
  99. px2rpx(px, screenWidth) {
  100. return px / (screenWidth / 750);
  101. },
  102. touchstart(e) {
  103. if (this.disable) return;
  104. this.x = this.px2rpx(e.touches[0].clientX, this.screenWidth);
  105. },
  106. touchmove(e) {
  107. if (this.disable) return;
  108. let clientX = this.x - this.px2rpx(e.touches[0].clientX, this.screenWidth);
  109. if (clientX <= 0) this.left = 0;
  110. else if (this.operation <= clientX) this.left = this.operation * -1;
  111. else this.left = clientX * -1;
  112. },
  113. touchend(e) {
  114. if (this.disable) return;
  115. let clientX = this.x - this.px2rpx(e.changedTouches[0].clientX, this.screenWidth);
  116. this.left = clientX > this.operation / 2 ? this.operation * -1 : 0;
  117. },
  118. },
  119. };
  120. </script>
  121. <style scoped>
  122. .slide {
  123. width: 100%;
  124. position: relative;
  125. overflow: hidden;
  126. }
  127. .slide-left {
  128. width: 100%;
  129. overflow: hidden;
  130. background-color: #ffffff;
  131. transition: left 0.2s ease-in-out;
  132. z-index: 999;
  133. }
  134. .slide-right {
  135. position: absolute;
  136. top: 0rpx;
  137. right: 0;
  138. z-index: 99;
  139. display: flex;
  140. align-items: center;
  141. justify-content: flex-end;
  142. }
  143. .btn-item {
  144. display: flex;
  145. align-items: center;
  146. justify-content: center;
  147. }
  148. </style>