资讯动态

VueUse usePermission 实战指南:在 Vue 应用中响应式管理浏览器权限状态

发布时间:2026/9/10 12:59:10 来源:尧图企业网站定制
VueUse usePermission 实战指南在 Vue 应用中响应式管理浏览器权限状态【免费下载链接】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-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi本文聚焦 VueUse 核心 Browser 组合式函数usePermission它把浏览器的 Permissions API 与 audio-device.ts 等源码实例讲透usePermission的用法、完整类型声明、响应式原理与实战落地方案读完即可在语音聊天、音视频采集等场景中直接落地。usePermission 是什么响应式封装 Permissions APIusePermission的定位是Reactive Permissions API——它不重新发明权限系统而是把浏览器原生的 Permissions API 变成 Vue 的响应式数据源。Permissions API 的价值在于它允许开发者在真正发起getUserMedia、Notification.requestPermission()等请求之前先查询某个权限的当前状态从而设计更好的用户体验例如提前展示权限尚未授权的引导卡片而不是等到调用时被浏览器拦截。VueUse 官方参考文档对其的描述为提供工具让开发者围绕权限实现更好的用户体验。对应的 Skill 分类中usePermission属于Browser浏览器类别调用策略为AUTO——在 Vue/Nuxt 开发中遇到权限状态跟踪需求时可自动选用其参考文档位于 .agents/skills/vueuse-functions/references/usePermission.md。快速上手一行代码拿到响应式权限状态最基础的用法只需传入权限描述符名称import { usePermission } from vueuse/core const microphoneAccess usePermission(microphone)此时microphoneAccess是一个响应式引用ShallowRefPermissionState | undefined其值会跟随浏览器权限变化自动更新取值可能是granted已授权denied已拒绝prompt尚未决定等待用户响应浏览器弹出的授权请求undefined当前环境不支持该权限查询如非安全上下文、不支持 Permissions API 的环境等。在模板或watch中直接使用即可script setup langts import { usePermission } from vueuse/core const notificationAccess usePermission(notifications) /script template button :disablednotificationAccess ! granted 通知状态{{ notificationAccess }} /button /template完整类型声明解析参考文档给出了usePermission的完整类型契约理解这些类型是安全使用的前提type DescriptorNamePolyfill | accelerometer | accessibility-events | ambient-light-sensor | background-sync | camera | clipboard-read | clipboard-write | gyroscope | magnetometer | microphone | notifications | payment-handler | persistent-storage | push | speaker | local-fonts export type GeneralPermissionDescriptor | PermissionDescriptor | { name: DescriptorNamePolyfill } export interface UsePermissionOptions Controls extends boolean, extends ConfigurableNavigator { /** * Expose more controls * * default false */ controls?: Controls } export type UsePermissionReturn Readonly ShallowRefPermissionState | undefined export interface UsePermissionReturnWithControls extends Supportable { state: UsePermissionReturn query: () PromisePermissionStatus | undefined } /** * Reactive Permissions API. */ export declare function usePermission( permissionDesc: | GeneralPermissionDescriptor | GeneralPermissionDescriptor[name], options?: UsePermissionOptionsfalse, ): UsePermissionReturn export declare function usePermission( permissionDesc: | GeneralPermissionDescriptor | GeneralPermissionDescriptor[name], options: UsePermissionOptionstrue, ): UsePermissionReturnWithControls第一个参数权限描述符usePermission的第一个参数接受两种形式字符串名称GeneralPermissionDescriptor[name]直接传microphone、camera、notifications等描述符对象GeneralPermissionDescriptor即标准PermissionDescriptor例如{ name: push, userVisibleOnly: true }——部分权限如push需要附加选项此时必须使用对象形式。其中DescriptorNamePolyfill列出的是 VueUse 为浏览器尚未标准化的权限名称提供的polyfill 描述符类型包括权限名称含义accelerometer加速度计传感器accessibility-events无障碍辅助事件ambient-light-sensor环境光传感器background-sync后台同步camera摄像头clipboard-read/clipboard-write剪贴板读 / 写gyroscope陀螺仪magnetometer磁力计microphone麦克风notifications桌面通知payment-handler支付处理器persistent-storage持久化存储push推送消息speaker扬声器local-fonts本地字体访问这些名称在部分浏览器中并未实现为 Permissions API 的标准PermissionName因此被归入 polyfill 集合意味着查询时可能返回undefined或依赖浏览器扩展实现。第二个参数optionsUsePermissionOptionsControls继承自ConfigurableNavigator即可通过navigator选项注入自定义的 navigator 对象便于测试与 SSR 场景核心选项为controls: boolean——默认false。设为true后返回值从仅状态升级为状态 手动查询控制。两种返回值形态根据controls是否开启返回类型分为默认形态UsePermissionReturnReadonlyShallowRefPermissionState | undefined。Readonly保证外部只能读不能写避免绕过浏览器权限系统直接篡改状态ShallowRef保证外层引用替换即可触发响应无需深层代理。开启controls后的形态UsePermissionReturnWithControlsstate: UsePermissionReturn——与默认形态相同的权限状态query: () PromisePermissionStatus | undefined——手动重新执行权限查询返回原生PermissionStatus或undefined不支持时该类型extends Supportable即同时暴露isSupported标志用于判断当前环境是否支持 Permissions API便于在 UI 上降级或隐藏权限引导。函数重载usePermission声明了两个重载options?: UsePermissionOptionsfalse→UsePermissionReturnoptions: UsePermissionOptionstrue→UsePermissionReturnWithControls。配合 TypeScript 重载controls: true时能够精确推断出带query与isSupported的返回类型无需手动断言。响应式原理状态如何自动更新从类型契约可以看出usePermission返回的是ShallowRef其核心机制可以推断为在初始化时调用navigator.permissions.query(descriptor)得到原生PermissionStatus对象取出status.state作为ShallowRef的初始值通过status.addEventListener(change, ...)监听权限状态变化一旦用户授予、拒绝或撤销权限立即更新 ref 的值组件卸载或副作用作用域销毁时自动移除事件监听避免内存泄漏。因此usePermission不是一次性查询而是持续跟随的响应式订阅——这正是它比手动调用navigator.permissions.query更适合 Vue 组合式开发的根本原因也符合其函数声明上的__NO_SIDE_EFFECTS__标记可被 tree-shaking 与副作用分析安全处理。仓库实战权限面板中的麦克风与通知权限在本仓库中usePermission所封装的 Permissions API 思想被直接用于真实的权限管理 UI。stage-pocketCapacitor 移动端应用的 permissions-panel.vue 构建了一个引导用户授权通知 麦克风的面板其中 Web 端麦克风权限检查正是手动使用 Permissions APIconst permission await navigator.permissions?.query({ name: microphone }).catch(() undefined) platformMicrophonePermissionGranted.value permission ? permission.state granted : webMicrophonePermissionGranted.value这段代码等价于usePermission(microphone)背后所做工作的手写版通过navigator.permissions.query({ name: microphone })查询麦克风权限将permission.state与granted比较得出布尔状态当 Permissions API 不可用时permission为undefined则回退到来自音频设备组合式函数的webMicrophonePermissionGranted兜底判断——这恰好印证了usePermission返回类型中undefined分支的实战意义查询不可用时必须准备降级方案。面板还使用了useLocalStorage(permissions/microphone/requested, false)来自 VueUse持久化是否已请求过权限的标记在原生平台上据此决定是再次请求授权还是直接跳转系统设置NativeSettings.open并监听appStateChange在应用回到前台时通过refreshPermissionStates刷新权限状态。与音频设备组合式函数的协作usePermission通常不是孤立使用的权限状态是入口真正采集音视频还需要与useUserMedia、useDevicesList协作。本仓库的 audio-device.ts 展示了这一分工import { useDevicesList, useUserMedia } from vueuse/core const { devices, audioInputs, permissionGranted, ensurePermissions, } useDevicesList({ constraints: { audio: true }, requestPermissions: requestPermission, })其中useDevicesList内部同样依赖 Permissions API 获取permissionGranted状态并负责枚举麦克风设备useUserMedia则真正发起getUserMedia流。而错误处理逻辑将浏览器错误归一化为两类NotAllowedError/PermissionDeniedError→permission_denied用户拒绝授权NotFoundError/OverconstrainedError/ Requested device not found →device_unavailable设备缺失或约束不满足。这套错误分类与usePermission的denied状态相互印证在 UI 层先通过usePermission(microphone)得知是否已拒绝denied再决定是展示去设置中开启引导还是直接发起getUserMedia在调用层通过useUserMedia捕获NotAllowedError兜底处理用户在浏览器地址栏临时改变授权的边缘情况。该组合式函数对应的权限状态管理还被封装为 Pinia storesettings/audio-device.ts对外暴露askPermission、startStream、stopStream、permissionGranted等 API供设置面板与语音对话场景消费。在项目中落地的完整建议结合参考文档的类型契约与本仓库实践给出以下落地清单优先使用usePermission而非手写navigator.permissions.query参考文档的Usage表明一行即可获得响应式状态手写版本需要自行维护change事件监听与清理逻辑见 permissions-panel.vue 的手写示例对比。需要手动重查时开启controls: true获得state、query与isSupported三件套const { state, query, isSupported } usePermission(microphone, { controls: true }) // 例如从系统设置返回后手动刷新 await query()务必处理undefined与isSupported false在非安全上下文HTTP 而非 HTTPS或老浏览器中 Permissions API 不可用此时应像 permissions-panel.vue 那样准备回退逻辑如直接尝试getUserMedia并捕获错误。与useUserMedia/useDevicesList分层使用usePermission负责状态感知与 UI 引导useUserMedia负责实际采集与错误归一化useDevicesList负责设备枚举与默认设备选择三者组合可以构建完整的音视频权限体验参考 audio-device.ts 的组合方式。注意查询即检查不等于请求usePermission查询prompt状态不等于弹出授权框真正的授权请求仍需通过Notification.requestPermission()或getUserMedia触发usePermission的价值在于让 UI 在请求前就知道该展示什么、请求后能立即响应变化。小结usePermission是 VueUse 对浏览器 Permissions API 的极简响应式封装一个ShallowRef订阅权限状态变化一套完整 TypeScript 类型含 polyfill 描述符、controls选项、Supportable返回值覆盖主流权限名称与降级场景。从本仓库的权限面板到音频设备管理其状态感知 → UI 引导 → 请求授权 → 错误归一的链路清晰可复用。建议开发者在 Vue 3 / Nuxt 3 项目中直接选用该 composableSkill 中调用策略为AUTO并配套useUserMedia、useDevicesList落地完整的多媒体权限体验。【免费下载链接】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-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价