location.ts 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import { defineStore } from 'pinia'
  2. import { ref } from 'vue'
  3. import { getUserLocation } from '@/utils/geo'
  4. type LocationFn = () => Promise<{ lng: number; lat: number }>
  5. export const useLocationStore = defineStore('location', () => {
  6. const lng = ref<number | null>(null)
  7. const lat = ref<number | null>(null)
  8. const located = ref(false)
  9. let timer: ReturnType<typeof setInterval> | null = null
  10. let overriddenFn: LocationFn | null = null
  11. function setLocationFn(fn: LocationFn) {
  12. overriddenFn = fn
  13. }
  14. function setLocation(longitude: number, latitude: number) {
  15. lng.value = longitude
  16. lat.value = latitude
  17. located.value = true
  18. }
  19. async function refreshLocation() {
  20. try {
  21. const fn = overriddenFn || getUserLocation
  22. const pos = await fn()
  23. setLocation(pos.lng, pos.lat)
  24. } catch {
  25. // 保留上次位置
  26. }
  27. }
  28. function startWatch(intervalMs = 5000) {
  29. stopWatch()
  30. refreshLocation()
  31. timer = setInterval(refreshLocation, intervalMs)
  32. }
  33. function stopWatch() {
  34. if (timer) {
  35. clearInterval(timer)
  36. timer = null
  37. }
  38. }
  39. return { lng, lat, located, setLocation, setLocationFn, refreshLocation, startWatch, stopWatch }
  40. })