touchMixin.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. function getDirection(x, y) {
  2. if (x > y) {
  3. return 'horizontal';
  4. }
  5. if (y > x) {
  6. return 'vertical';
  7. }
  8. return '';
  9. }
  10. export const touchMixin = {
  11. data() {
  12. return {
  13. direction: '',
  14. startX: '',
  15. startY: '',
  16. nextIndex: -1,
  17. moved: false, //是否为一次水平滑动
  18. };
  19. },
  20. methods: {
  21. touchStart(event) {
  22. if (!this.swipeable) { return }
  23. this.resetTouchStatus();
  24. this.startX = event.touches[0].clientX;
  25. this.startY = event.touches[0].clientY;
  26. },
  27. touchMove(event) {
  28. const touch = event.touches[0];
  29. this.deltaX = touch.clientX < 0 ? 0 : touch.clientX - this.startX;
  30. this.deltaY = touch.clientY - this.startY;
  31. const offsetX = Math.abs(this.deltaX);
  32. const offsetY = Math.abs(this.deltaY);
  33. // 当距离大于某个值时锁定方向
  34. const lock_distance = 10;
  35. if (!this.direction || (offsetX < lock_distance && offsetY < lock_distance)) {
  36. this.direction = getDirection(offsetX, offsetY);
  37. }
  38. if (this.direction === "horizontal") { //水平滑动
  39. const { deltaX, dataLen, contentWidth, currentIndex, swipeAnimated } = this
  40. // 如果当前为第一页内容,则不允许向右滑;最后一页内容,则不允许左滑
  41. if ((deltaX > 0 && currentIndex === 0) || (deltaX < 0 && currentIndex === dataLen - 1)) {
  42. return
  43. }
  44. this.nextIndex = currentIndex + (deltaX > 0 ? -1 : 1)
  45. this.moved = true //标记为一次水平滑动
  46. // 改变标签内容的样式,模拟拖动动画效果
  47. if (swipeAnimated) {
  48. const offsetWidth = contentWidth * currentIndex * -1 + deltaX
  49. this.changeTrackStyle(true, 0, offsetWidth)
  50. }
  51. }
  52. },
  53. touchEnd() {
  54. if (!this.moved) { return }
  55. const { deltaX, nextIndex, dataLen, swipeThreshold } = this;
  56. if (Math.abs(deltaX) >= swipeThreshold) { //当滑动距离大于某个值时切换标签
  57. this.setCurrentIndex(nextIndex)
  58. } else { //否则还原
  59. this.changeTrackStyle(false)
  60. }
  61. },
  62. resetTouchStatus() {
  63. this.direction = '';
  64. this.deltaX = 0;
  65. this.deltaY = 0;
  66. this.newIndex = -1;
  67. this.moved = false;
  68. },
  69. }
  70. }