金诚优选前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
6.9 KiB

  1. <template>
  2. <view class="swipe_action_box" @touchstart="onTouchstart" @touchmove="onTouchmove" @touchcancel="onTouchcancel" @touchend="onTouchend">
  3. <view class="swipe_action_item" :style="{ width: (screenWidth + maxWidth) + 'px', transform: 'translateX(' + translateX + 'px)', transition: 'transform ' + animationTime + 'ms cubic-bezier(.165, .84, .44, 1)' }">
  4. <view class="swipe_action_content"><slot></slot></view>
  5. <view class="swipe_action_btn_box" ref="swipeActionBtnBox" :class="{'mune-show': mune_show}">
  6. <view v-for="(item,index) of options" :key="index" class="swipe_action_btn" :style="{
  7. backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
  8. }" @click.stop="onBtn(index,item)">
  9. <text :style="{
  10. fontSize: item.style && item.style.fontSize ? item.style.fontSize : '14px',
  11. color: item.style && item.style.color ? item.style.color : '#FFFFFF'
  12. }">{{ item.text }}</text>
  13. </view>
  14. </view>
  15. </view>
  16. </view>
  17. </template>
  18. <script>
  19. // #ifdef APP-NVUE
  20. const dom = weex.requireModule('dom');
  21. // #endif
  22. export default {
  23. props: {
  24. /**
  25. * 按钮内容
  26. */
  27. options: {
  28. type: Array,
  29. default () {
  30. return []
  31. }
  32. },
  33. /**
  34. * 禁用
  35. */
  36. disabled: {
  37. type: Boolean,
  38. default: false
  39. },
  40. /**
  41. * 变量控制开关
  42. */
  43. show: {
  44. type: Boolean,
  45. default: false
  46. },
  47. /**
  48. * 是否自动关闭
  49. */
  50. autoClose: {
  51. type: Boolean,
  52. default: true
  53. },
  54. /**
  55. * swipe-action 的索引值
  56. */
  57. index: {
  58. type: Number,
  59. default: 0
  60. }
  61. },
  62. data() {
  63. return {
  64. //开始触摸时间
  65. startTime: 0,
  66. //开始触摸距离
  67. touchStartX: 0,
  68. //最大距离
  69. maxWidth: 58,
  70. //滑动距离
  71. translateX: 0,
  72. animationTime: 0,
  73. //上次的位置
  74. currentX: 0,
  75. screenWidth: 0,
  76. mune_show: false
  77. };
  78. },
  79. watch:{
  80. show(val){
  81. if(val){
  82. this.animationTime = 350;
  83. this.translateX = -this.maxWidth;
  84. }else {
  85. this.animationTime = 350;
  86. this.translateX = 0;
  87. }
  88. },
  89. translateX(val){
  90. if(val == 0){
  91. this.mune_show = false;
  92. }else{
  93. this.mune_show = true;
  94. }
  95. }
  96. },
  97. created() {
  98. let systemInfo = uni.getSystemInfoSync();
  99. this.screenWidth = systemInfo.screenWidth;
  100. },
  101. mounted() {
  102. const _this = this;
  103. setTimeout(() => {
  104. // #ifdef APP-NVUE
  105. dom.getComponentRect(this.$refs['swipeActionBtnBox'], (data) => {
  106. _this.maxWidth = data.size.width;
  107. if(_this.show){
  108. _this.animationTime = 350;
  109. _this.translateX = -data.size.width;
  110. }
  111. });
  112. // #endif
  113. // #ifndef APP-NVUE
  114. uni.createSelectorQuery().in(this).selectAll('.swipe_action_btn_box')
  115. .boundingClientRect(data => {
  116. _this.maxWidth = data[0].width;
  117. if(_this.show){
  118. _this.animationTime = 350;
  119. _this.translateX = -data[0].width;
  120. }
  121. }).exec()
  122. // #endif
  123. },500);
  124. },
  125. //方法
  126. methods: {
  127. onBtn(index, item) {
  128. this.$emit('button', {
  129. content: item,
  130. index: this.index,
  131. buttonIndex: index
  132. });
  133. if(this.autoClose){
  134. this.animationTime = 350;
  135. this.translateX = 0;
  136. }
  137. },
  138. // 手指触摸动作开始
  139. onTouchstart(e) {
  140. if(this.disabled){
  141. return;
  142. }
  143. //储存手指触摸坐标,当前时间戳,当前坐标
  144. // #ifdef APP-NVUE
  145. this.touchStartX = e.changedTouches[0].screenX;
  146. // #endif
  147. // #ifndef APP-NVUE
  148. this.touchStartX = e.changedTouches[0].clientX;
  149. // #endif
  150. this.startTime = new Date().getTime();
  151. this.currentX = this.translateX;
  152. },
  153. // 手指触摸后移动
  154. onTouchmove(e) {
  155. if(this.disabled){
  156. return;
  157. }
  158. //手指当前坐标
  159. // #ifdef APP-NVUE
  160. const clientX = e.changedTouches[0].screenX;
  161. // #endif
  162. // #ifndef APP-NVUE
  163. const clientX = e.changedTouches[0].clientX;
  164. // #endif
  165. //计算滑动距离
  166. const difference = this.touchStartX - clientX;
  167. //判断左滑还是右滑
  168. if (difference > 0) {
  169. //计算当前已滑动距离
  170. const leftDifference = this.currentX - Math.abs(difference);
  171. //判断是否大于滑动的最大宽度
  172. if (this.maxWidth < Math.abs(leftDifference)) {
  173. this.animationTime = 0;
  174. this.translateX = -this.maxWidth;
  175. } else {
  176. this.animationTime = 0;
  177. this.translateX = leftDifference;
  178. }
  179. } else {
  180. const rightDifference = this.currentX + Math.abs(difference);
  181. if (0 < rightDifference) {
  182. this.animationTime = 0;
  183. this.translateX = 0;
  184. } else {
  185. this.animationTime = 0;
  186. this.translateX = rightDifference;
  187. }
  188. }
  189. },
  190. // 手指触摸动作被打断,如来电提醒,弹窗
  191. onTouchcancel(e) {
  192. if(this.disabled){
  193. return;
  194. }
  195. // #ifdef APP-NVUE
  196. this.finallySlide(e.changedTouches[0].screenX);
  197. // #endif
  198. // #ifndef APP-NVUE
  199. this.finallySlide(e.changedTouches[0].clientX);
  200. // #endif
  201. },
  202. // 手指触摸动作结束
  203. onTouchend(e) {
  204. if(this.disabled){
  205. return;
  206. }
  207. // #ifdef APP-NVUE
  208. this.finallySlide(e.changedTouches[0].screenX);
  209. // #endif
  210. // #ifndef APP-NVUE
  211. this.finallySlide(e.changedTouches[0].clientX);
  212. // #endif
  213. },
  214. //最终判断滑动
  215. finallySlide(finallyX) {
  216. //手指离开的时间
  217. const endTime = new Date().getTime();
  218. //手机滑动屏幕的总花费时间
  219. const timeDifference = endTime - this.startTime;
  220. //手指触摸总滑动距离
  221. const distanceDifference = this.touchStartX - finallyX;
  222. //判断最终滑动方向
  223. if (distanceDifference > 0) {
  224. //判断是否滑动到左边 滑动距离超过3分之一 或者 滑动时间在300毫秒并且距离在4分之一
  225. if (Math.abs(this.translateX) > this.maxWidth / 2 || (timeDifference < 300 && distanceDifference > this.maxWidth / 4)) {
  226. this.animationTime = 350;
  227. this.translateX = -this.maxWidth;
  228. } else {
  229. this.animationTime = 350;
  230. this.translateX = 0;
  231. }
  232. } else if (distanceDifference < 0) {
  233. //判断是否滑动到右边 滑动距离超过3分之一 或者 滑动时间在300毫秒并且距离在4分之一
  234. if (Math.abs(this.translateX) < this.maxWidth / 2 || (timeDifference < 300 && Math.abs(distanceDifference) > this.maxWidth / 4)) {
  235. this.animationTime = 350;
  236. this.translateX = 0;
  237. } else {
  238. this.animationTime = 350;
  239. this.translateX = -this.maxWidth;
  240. }
  241. }
  242. }
  243. }
  244. };
  245. </script>
  246. <style scoped>
  247. .swipe_action_box {
  248. overflow: hidden;
  249. width: 750rpx;
  250. }
  251. .swipe_action_item {
  252. /* #ifndef APP-NVUE */
  253. display: flex;
  254. /* #endif */
  255. flex-direction: row;
  256. }
  257. .swipe_action_content {
  258. /* width: 750rpx; */
  259. width: max-content;
  260. /* #ifndef APP-NVUE */
  261. flex-shrink: 0;
  262. /* #endif */
  263. }
  264. .swipe_action_btn_box {
  265. /* #ifndef APP-NVUE */
  266. display: flex;
  267. flex-shrink: 0;
  268. /* #endif */
  269. flex-direction: row;
  270. visibility: hidden;
  271. }
  272. .mune-show{
  273. visibility: initial;
  274. }
  275. .swipe_action_btn {
  276. /* #ifndef APP-NVUE */
  277. display: flex;
  278. /* #endif */
  279. flex-direction: row;
  280. align-items: center;
  281. justify-content: center;
  282. padding: 0 30rpx;
  283. }
  284. .swipe_action_btn:nth-child(1){
  285. margin-left: 20rpx;
  286. }
  287. </style>