金诚优选前端代码
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.

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