SwipeAction.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. },
  50. data() {
  51. return {
  52. x: 0,
  53. left: 0,
  54. operation: 0,
  55. height: 0,
  56. screenWidth: 0,
  57. };
  58. },
  59. mounted() {
  60. this.$nextTick((res) => {
  61. const systemInfo = uni.getSystemInfoSync();
  62. this.screenWidth = systemInfo.screenWidth;
  63. this.getBtnWidth();
  64. this.getListHeight();
  65. });
  66. },
  67. methods: {
  68. clickItem(e) {
  69. this.$emit("clickItem", {
  70. index: this.index,
  71. id: e.id,
  72. });
  73. },
  74. //重置方法
  75. reset() {
  76. this.left = 0;
  77. },
  78. getBtnWidth() {
  79. let view = uni.createSelectorQuery().in(this).select(".slide-right");
  80. view
  81. .boundingClientRect((rect) => {
  82. this.operation = this.px2rpx(rect.width, this.screenWidth);
  83. })
  84. .exec();
  85. },
  86. getListHeight() {
  87. let view = uni.createSelectorQuery().in(this).select(".slide-left");
  88. view
  89. .boundingClientRect((rect) => {
  90. this.height = this.px2rpx(rect.height, this.screenWidth);
  91. })
  92. .exec();
  93. },
  94. px2rpx(px, screenWidth) {
  95. return px / (screenWidth / 750);
  96. },
  97. touchstart(e) {
  98. if (this.disable) return;
  99. this.x = this.px2rpx(e.touches[0].clientX, this.screenWidth);
  100. },
  101. touchmove(e) {
  102. if (this.disable) return;
  103. let clientX = this.x - this.px2rpx(e.touches[0].clientX, this.screenWidth);
  104. if (clientX <= 0) this.left = 0;
  105. else if (this.operation <= clientX) this.left = this.operation * -1;
  106. else this.left = clientX * -1;
  107. },
  108. touchend(e) {
  109. if (this.disable) return;
  110. let clientX = this.x - this.px2rpx(e.changedTouches[0].clientX, this.screenWidth);
  111. this.left = clientX > this.operation / 2 ? this.operation * -1 : 0;
  112. },
  113. },
  114. };
  115. </script>
  116. <style scoped>
  117. .slide {
  118. width: 100%;
  119. position: relative;
  120. overflow: hidden;
  121. }
  122. .slide-left {
  123. width: 100%;
  124. overflow: hidden;
  125. background-color: #ffffff;
  126. transition: left 0.2s ease-in-out;
  127. z-index: 999;
  128. }
  129. .slide-right {
  130. position: absolute;
  131. top: 0rpx;
  132. right: 0;
  133. z-index: 99;
  134. display: flex;
  135. align-items: center;
  136. justify-content: flex-end;
  137. }
  138. .btn-item {
  139. display: flex;
  140. align-items: center;
  141. justify-content: center;
  142. }
  143. </style>