long-press.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { onUnmounted, ref, type Ref } from "vue";
  2. // 长按触发延迟时间,单位毫秒
  3. const DELAY = 500;
  4. // 长按重复执行间隔时间,单位毫秒
  5. const REPEAT = 100;
  6. /**
  7. * 长按操作钩子函数返回类型
  8. */
  9. type UseLongPress = {
  10. // 开始长按
  11. start: (cb: () => void) => void;
  12. // 停止长按
  13. stop: () => void;
  14. // 清除定时器
  15. clear: () => void;
  16. // 是否正在长按中
  17. isPressing: Ref<boolean>;
  18. };
  19. /**
  20. * 长按操作钩子函数
  21. * 支持长按持续触发,可用于数字输入框等需要连续操作的场景
  22. */
  23. export const useLongPress = (): UseLongPress => {
  24. // 是否正在长按中
  25. const isPressing = ref(false);
  26. // 长按延迟定时器
  27. let pressTimer: number = 0;
  28. // 重复执行定时器
  29. let repeatTimer: number = 0;
  30. /**
  31. * 清除所有定时器
  32. * 重置长按状态
  33. */
  34. const clear = () => {
  35. // 清除长按延迟定时器
  36. if (pressTimer != 0) {
  37. clearTimeout(pressTimer);
  38. pressTimer = 0;
  39. }
  40. // 清除重复执行定时器
  41. if (repeatTimer != 0) {
  42. clearInterval(repeatTimer);
  43. repeatTimer = 0;
  44. }
  45. // 重置长按状态
  46. isPressing.value = false;
  47. };
  48. /**
  49. * 开始长按操作
  50. * @param cb 长按时重复执行的回调函数
  51. */
  52. const start = (cb: () => void) => {
  53. // 清除已有定时器
  54. clear();
  55. // 立即执行一次回调
  56. cb();
  57. // 延迟500ms后开始长按
  58. // @ts-ignore
  59. pressTimer = setTimeout(() => {
  60. // 震动
  61. uni.$emit("cool.vibrate");
  62. // 设置长按状态
  63. isPressing.value = true;
  64. // 每100ms重复执行回调
  65. // @ts-ignore
  66. repeatTimer = setInterval(() => {
  67. cb();
  68. }, REPEAT);
  69. }, DELAY);
  70. };
  71. /**
  72. * 停止长按操作
  73. * 清除定时器并重置状态
  74. */
  75. const stop = () => {
  76. clear();
  77. };
  78. // 组件卸载时清理定时器
  79. onUnmounted(() => {
  80. clear();
  81. });
  82. return {
  83. start,
  84. stop,
  85. clear,
  86. isPressing
  87. };
  88. };