useEmailCountdown.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // hooks/useEmailCountdown.ts
  2. import { ref, computed, onUnmounted } from 'vue'
  3. import { useI18n } from 'vue-i18n'
  4. import ls from "@/utils/store2";
  5. interface UseEmailCountdownOptions {
  6. duration?: number
  7. storageKey?: string
  8. }
  9. export function useEmailCountdown(options: UseEmailCountdownOptions) {
  10. const { t } = useI18n()
  11. const {
  12. duration = 60,
  13. storageKey = 'email_countdown'
  14. } = options || {}
  15. const time = ref<number>(duration)
  16. const endTime = ref<number>(0)
  17. let timer: ReturnType<typeof setInterval> | null = null
  18. const text = computed(() => {
  19. if (time.value === duration) {
  20. return t('newSignup.item11')
  21. }
  22. return `${t('signup.form.waitCode1')}${time.value}${t('signup.form.waitCode2')}`
  23. })
  24. const canSend = computed(() => time.value === duration)
  25. const tick = () => {
  26. const remain = Math.floor((endTime.value - Date.now()) / 1000)
  27. time.value = remain > 0 ? remain : duration;
  28. if (time.value === duration) {
  29. clear()
  30. }
  31. }
  32. const start = () => {
  33. clear()
  34. endTime.value = Date.now() + duration * 1000
  35. ls.set(storageKey, String(endTime.value))
  36. tick()
  37. timer = setInterval(tick, 1000)
  38. }
  39. const restore = () => {
  40. const saved = Number(ls.get(storageKey))
  41. if (!saved) return
  42. if (saved > Date.now()) {
  43. endTime.value = saved
  44. tick()
  45. timer = setInterval(tick, 1000)
  46. }
  47. }
  48. const clear = () => {
  49. if (timer) {
  50. clearInterval(timer)
  51. timer = null
  52. // time.value = duration
  53. }
  54. ls.set(storageKey, '')
  55. }
  56. onUnmounted(clear)
  57. return {
  58. time,
  59. text,
  60. canSend,
  61. start,
  62. restore,
  63. clear
  64. }
  65. }