airi 项目中的 VueUse useGeolocation:浏览器 Geolocation API 的响应式封装全解
2026/9/10 7:43:20 网站建设 项目流程

airi 项目中的 VueUse useGeolocation:浏览器 Geolocation API 的响应式封装全解

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

本篇基于 airi 仓库内置的 VueUse 技能参考文档 useGeolocation,系统讲解useGeolocation如何把浏览器 Geolocation API 封装为可响应式消费的坐标状态:读完你可以掌握它的完整返回值结构(coords/locatedAt/error/resume/pause)、PositionOptions配置项与immediate等自定义选项、组件式(<UseGeolocation>)用法,以及在 airi 这类多端 Vue 3 应用(Web / macOS / Windows 桌面端)中正确接入位置能力、处理权限与暂停/恢复的实战模式。

背景:airi 仓库中的 VueUse 技能参考文档

airi 是一个自托管的 AI 陪伴/虚拟角色项目(Web、macOS、Windows 多端运行),其前端各应用(stage-web、stage-tamagotchi、stage-pocket、ui-server-auth 等)均通过 pnpm catalog 统一依赖@vueuse/core(版本^14.4.0,见 pnpm-workspace.yaml)。

仓库在 .agents/skills/vueuse-functions 目录内置了一份 VueUse 函数技能参考,作为 AI Agent 与开发者在 Vue/Nuxt 项目中选型可组合函数(composable)的决策指南。按 SYNC.md 的同步信息,该技能文档来源于 VueUse 官方技能仓库(Git SHAb6bb79b99fb1f1dba1f907829676a651735bbc10,同步日期 2026-06-22)。在 SKILL.md 的Sensors(传感器)分类表中,useGeolocation的描述为:

Reactive [Geolocation API],调用规则(Invocation)为AUTO——即在适用场景下可以自动采用,无需用户显式要求。

这意味着在 airi 的前端代码中,若需求是“追踪用户地理位置”,首选方案不是手写navigator.geolocation.watchPosition加回调管理,而是直接使用useGeolocation,获得与 Vue 响应式系统天然集成的坐标状态。

核心概念:把 Geolocation API 变成响应式状态

浏览器的 Geolocation API 允许 Web 应用在用户授权的情况下获取其位置信息。出于隐私考虑,浏览器会先向用户弹出“是否共享您的位置”的权限询问;用户同意后,应用才能拿到经纬度等坐标数据。

传统用法需要手动处理getCurrentPosition/watchPosition的回调、错误回调、监听句柄的清理,生命周期管理容易出错。useGeolocation将其封装为一个可组合函数:调用后返回一组ShallowRef状态与控制函数,坐标更新会自动触发依赖它的模板与计算属性重新渲染,无需手写任何事件绑定与清理逻辑。

基本用法

@vueuse/core导入并调用:

import { useGeolocation } from '@vueuse/core' const { coords, locatedAt, error, resume, pause } = useGeolocation()

resume/pause在需要用户手动开启/关闭位置追踪时特别有用,例如页面上放一个开关,pause()停止watchPosition监听以节省设备 GPS 功耗,resume()恢复监听。

返回值状态一览

状态类型说明
coordsCoordinates对象获取到的位置信息,包含latitude(纬度)、longitude(经度)等坐标字段
locatedAtDate(时间戳)最近一次定位成功的时间
error错误信息定位失败时的错误对象/消息(权限被拒、超时等)
resumefunction恢复位置更新的控制函数
pausefunction暂停位置更新的控制函数

其中coords是响应式引用,坐标每次刷新时模板会自动更新;error在用户拒绝授权或定位失败时会被赋值,是权限与失败处理的主要观测点。

配置项:PositionOptions 与自定义选项

useGeolocation接收一个可选的UseGeolocationOptions对象作为参数。该接口继承了标准 PositionOptions 的全部字段,同时扩展了 VueUse 自有的immediate选项:

export interface UseGeolocationOptions extends Partial<PositionOptions>, ConfigurableNavigator { immediate?: boolean }

常用的PositionOptions字段包括:

字段类型/默认值作用
enableHighAccuracyboolean是否请求高精度定位(GPS 级别),默认false。开启后精度更高但耗电更多、速度更慢
timeoutnumber(毫秒)等待定位结果的超时时间
maximumAgenumber(毫秒)允许缓存定位结果的有效期;0表示每次都要求新鲜定位

UseGeolocationOptions额外提供的:

  • immediate?: boolean—— 控制是否立即发起定位。设置为false时,函数创建后不会立刻请求权限与坐标,需要等到手动resume()才开始更新,适合“用户点击按钮后才开始定位”的场景;
  • ConfigurableNavigator—— 允许传入自定义的navigator对象,主要服务于测试环境(可注入 mock 的geolocation实现)。

在 airi 的各端应用中,若需要定位能力,典型接入方式为:

import { useGeolocation } from '@vueuse/core' const { coords, locatedAt, error, pause } = useGeolocation({ enableHighAccuracy: true, timeout: 10000, immediate: true, // 组件创建即请求定位;设为 false 则等待 resume() }) // 坐标可用于地图标记、附近内容推荐等;定位失败/权限被拒时读取 error

组件式用法(Component Usage)

除可组合函数外,useGeolocation也提供了对应的 VueUse 组件形式。在需要把定位状态直接交给模板渲染的轻量场景中,可以直接使用<UseGeolocation>组件并通过v-slot解构坐标:

<template> <UseGeolocation v-slot="{ coords: { latitude, longitude } }"> 纬度: {{ latitude }} 经度: {{ longitude }} </UseGeolocation> </template>

这种写法把“状态获取 + 解构 + 渲染”压缩在模板一层内,适合调试页面或简单的坐标展示组件;而在 airi 这种逻辑较重的舞台应用中(如 stage-ui、stage-shared 各包),更常见的是在setup或 composable 中使用函数形式,以便与事件钩子、存储持久化(如useLocalStorage)等其他 VueUse 能力组合。

类型声明详解

参考文档给出的完整类型声明如下,逐字段解读可以明确其类型契约:

export interface UseGeolocationOptions extends Partial<PositionOptions>, ConfigurableNavigator { immediate?: boolean } export interface UseGeolocationReturn extends Supportable { coords: ShallowRef<Omit<GeolocationPosition["coords"], "toJSON">> locatedAt: ShallowRef<number | null> error: ShallowRef<GeolocationPositionError | null> resume: () => void pause: () => void } /** * Reactive Geolocation API. * * @see https://vueuse.org/useGeolocation * @param options */ export declare function useGeolocation( options?: UseGeolocationOptions, ): UseGeolocationReturn

从类型声明可以看出几个实现层面的要点:

  1. coords使用ShallowRefGeolocationPosition['coords']类型去掉了toJSON方法后作为值类型。使用浅引用意味着 Vue 不会对坐标对象做深层代理,更新时整体替换值即可触发响应式更新——这避免了在高频定位回调中对对象逐属性追踪的开销。
  2. locatedAtShallowRef<number | null>:初始为null,每次成功定位后写入时间戳;配合coords可判断“当前坐标的新鲜度”,例如在 UI 上显示“x 秒前定位”。
  3. errorShallowRef<GeolocationPositionError | null>:失败时写入标准的GeolocationPositionError,可按其code区分权限拒绝(PERMISSION_DENIED)与定位超时(TIMEOUT),做差异化的提示文案。
  4. 返回值继承Supportable:即带有isSupported属性(可组合函数会做 SSR 兼容判断),在缺少 Geolocation 能力的环境(如部分受限嵌入容器或 SSR 渲染路径)中应先检查isSupported再发起定位。

权限模型与错误处理实践

Geolocation API 的隐私模型决定了应用永远不能静默获取位置:

  • 首次请求即触发授权弹窗。用户拒绝后,error会被赋值为权限拒绝类型的错误,后续调用不会再弹窗(直到用户在浏览器设置中手动恢复授权)。因此 UI 上应把error状态渲染为可读的提示,并给出“去浏览器设置中开启位置权限”的引导,而不是反复重试。
  • pause()是省电手段watchPosition是持续监听,页面长期停留(airi 的桌面端/移动端应用常常长时间开着)时,不需要位置的功能模块应及时pause()停止 GPS 采样。
  • immediate: false是“惰性定位”的开关。把定位请求延迟到用户明确操作(点击“附近”按钮)之后,既改善隐私体验,也避免应用启动时不必要的权限询问。
  • 超时兜底。设置合理的timeout,防止在信号差的环境下定位 Promise 长时间悬空;error会在超时后反映 TIMEOUT 错误。

在 airi 仓库中,位置数据属于隐私敏感信息——其隐私政策文档(如 docs/content/privacy.md)明确列出了位置服务(Geolocation Services)用于位置相关的游戏与娱乐功能。从这一文档结构看,任何接入定位的前端功能都应遵循“按需请求、明示用途、可随时暂停”的原则,useGeolocation提供的pause/resumeimmediate正是为此设计的控制面。

小结

useGeolocation以极小的 API 面覆盖了 Geolocation 场景的完整生命周期:coords/locatedAt提供响应式位置数据,error暴露权限与失败状态,resume/pause控制监听的启停,immediatePositionOptions控制定位策略。对于 airi 这类同时运行于浏览器与 Electron/Capacitor 容器的多端应用,它是接入位置能力时最简洁且与 Vue 响应式系统无缝集成的方案。完整类型契约与用法参见 useGeolocation 参考文档,函数分类与调用规则(Sensors / AUTO)参见 SKILL.md。

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询