资讯动态

VueUse useBluetooth 全解析:在 Vue 3 中响应式接入 Web Bluetooth 低功耗设备

发布时间:2026/10/5 1:49:00 来源:尧图企业网站定制
前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载useBluetooth是 VueUse 为 Vue 3 提供的一个组合式函数它把浏览器原生的 Web Bluetooth API 封装成响应式状态让你能以声明式的方式发现、配对并连接蓝牙低功耗Bluetooth Low EnergyBLE外设。阅读完本文你将掌握useBluetooth的完整配置项、返回值语义、如何读取特征值如电池电量以及如何监听设备断开与数据变化并能直接落地到真实项目中。什么是 Web Bluetooth以及它适合做什么Web Bluetooth API 允许网站通过蓝牙 4 无线标准利用 Generic Attribute ProfileGATT协议发现并与周边设备通信。这意味着浏览器页面可以直接读取心率计、温度传感器、智能手环等 BLE 外设的数据无需安装任何本地驱动或原生应用。useBluetooth所做的正是把这一套底层 API 转化为 Vue 的响应式数据流核心能力包括检测当前环境是否支持 Web Bluetooth API弹出系统选择器请求用户授权并选择设备自动连接设备的 GATT 服务端追踪连接状态、设备对象、服务端对象与错误信息在组件卸载时自动断开连接并清理监听。基本用法请求并连接一台设备在script setup中引入useBluetooth并传入acceptAllDevices: true即可发起最简单的连接流程script setup langts import { useBluetooth } from vueuse/core const { isSupported, isConnected, device, requestDevice, server, error, } useBluetooth({ acceptAllDevices: true, }) /script template button clickrequestDevice() Request Bluetooth Device /button div v-iferror Error: {{ error }} /div /template点击按钮后浏览器会弹出设备选择器用户选定设备并授权后useBluetooth内部会自动完成 GATT 连接随后server与isConnected会响应式地更新。仓库中的 demo.vue 还额外展示了isSupported、device.name与连接状态的 UI 反馈写法可供参考。返回值一览属性类型说明isSupportedComputedRefboolean当前环境是否支持 Web Bluetooth APIisConnectedReadonlyShallowRefboolean设备当前是否已连接deviceShallowRefBluetoothDevice \| undefined已连接的蓝牙设备对象serverShallowRefBluetoothRemoteGATTServer \| undefined已连接设备的 GATT 服务端对象errorShallowRefunknown \| null请求或连接过程中产生的错误requestDevice() Promisevoid触发设备请求的函数当设备完成配对并连接成功后你就可以基于server对象自由地进行服务发现与特征值读写见下文电池电量示例。需要说明的是文档中这些返回值在源码 packages/core/useBluetooth/index.ts 里实际使用的是浅层响应式ShallowRef且isConnected通过shallowReadonly对外暴露为只读避免外部误改内部状态。isSupported则来自useSupported见 packages/core/useSupported/index.ts它会在组件挂载后计算navigator.bluetooth是否存在。进阶实战读取并订阅电池电量变化这个示例演示了如何用 Web Bluetooth 读取附近 BLE 设备广播的电池电量并监听后续的电量变化通知。核心思路是拿到battery_service服务再取得battery_level特征值通过characteristicvaluechanged事件持续接收最新电量。script setup langts import { useBluetooth, useEventListener, watchPausable } from vueuse/core const { isSupported, isConnected, device, requestDevice, server, } useBluetooth({ acceptAllDevices: true, optionalServices: [ battery_service, ], }) const batteryPercent refundefined | number() const isGettingBatteryLevels ref(false) async function getBatteryLevels() { isGettingBatteryLevels.value true // 获取电池服务 const batteryService await server.getPrimaryService(battery_service) // 获取当前电量特征值 const batteryLevelCharacteristic await batteryService.getCharacteristic( battery_level, ) // 监听特征值变化事件 characteristicvaluechanged useEventListener(batteryLevelCharacteristic, characteristicvaluechanged, (event) { batteryPercent.value event.target.value.getUint8(0) }, { passive: true }) // 主动读取一次当前电量 const batteryLevel await batteryLevelCharacteristic.readValue() batteryPercent.value await batteryLevel.getUint8(0) } const { stop } watchPausable(isConnected, (newIsConnected) { if (!newIsConnected || !server.value || isGettingBatteryLevels.value) return // 首次连接成功后读取电量 getBatteryLevels() // 后续变化由事件监听处理因此停止该 watcher stop() }) /script template button clickrequestDevice() Request Bluetooth Device /button /template这段代码有三个值得注意的技术细节optionalServices必不可少BLE 设备只会暴露其广播中声明的服务。battery_service这类标准服务必须在optionalServices中显式声明requestDevice才会把它们暴露给网页否则getPrimaryService(battery_service)会失败。事件监听代替轮询useEventListener把characteristicvaluechanged事件绑定到特征值对象上事件回调里event.target.value.getUint8(0)负责把 DataView 缓冲区中的第一个字节解析成 0–100 的电量百分比{ passive: true }声明该监听不会调用preventDefault()可获得更好的性能表现。一次性 watcher 的设计watchPausable监听isConnected只在首次连接成功时执行一次电量读取随即stop()停止监听后续电量变化全部交给事件回调处理避免重复初始化。需要提醒的是从源码看watchPausable当前已被标记为deprecated见 packages/shared/watchPausable/index.ts官方建议改用 Vue 内建的watch因此你在新代码中也可以直接写watch(isConnected, ...)并配合一个let once标志达到同样效果。配置项详解从过滤到精细匹配useBluetooth接受一个可选的UseBluetoothOptions配置对象其完整类型声明与源码中的定义一一对应packages/core/useBluetooth/index.tsexport interface UseBluetoothRequestDeviceOptions { /** * 一组蓝牙扫描过滤器。每个过滤器由服务 UUID 数组、 * name精确设备名与 namePrefix设备名前缀组成。 */ filters?: BluetoothLEScanFilter[] | undefined /** * 一组蓝牙服务 UUID用于声明需要访问的 GATT 服务。 */ optionalServices?: BluetoothServiceUUID[] | undefined } export interface UseBluetoothOptions extends UseBluetoothRequestDeviceOptions, ConfigurableNavigator { /** * 是否允许脚本接受所有蓝牙设备默认 false。 * * !! 开启后选择器可能列出大量无关设备 * 且由于没有过滤条件会浪费搜索功耗请谨慎使用。 */ acceptAllDevices?: boolean }各配置项的行为可以这样理解acceptAllDevices默认false允许页面接受任意蓝牙设备。它会在设备选择器中展示所有可发现的外设因此文档明确警告这可能导致无关设备扎堆、搜索功耗浪费。源码中的处理逻辑是如果同时传入了非空的filtersacceptAllDevices会被强制置回falsepackages/core/useBluetooth/index.ts因为两者语义冲突。filtersBluetoothLEScanFilter[]扫描过滤器数组。每个过滤器可以包含services服务 UUID、name精确设备名、namePrefix设备名前缀等字段用于精准缩小设备选择范围。从源码看只要filters非空最终传给navigator.bluetooth.requestDevice()的一定是acceptAllDevices: false。optionalServicesBluetoothServiceUUID[]服务 UUID 数组。用于声明页面希望访问的额外 GATT 服务标准服务名如battery_service或 16 位 / 128 位 UUID 均可。navigator来自ConfigurableNavigator定义见 packages/core/_configurable.ts允许你注入自定义navigator实例典型场景是在 iframe 或测试环境中替换全局对象。默认取window.navigator。底层实现连接、断开与自动清理的生命周期深入了解源码可以解释许多使用细节。useBluetooth的实现大致分为四个阶段packages/core/useBluetooth/index.ts能力检测useSupported(() navigator bluetooth in navigator)计算isSupported。requestDevice内部也会再次检查在不支持的环境下直接返回避免报错。请求设备requestDevice()调用navigator.bluetooth.requestDevice({ acceptAllDevices, filters, optionalServices })把device写入浅层 ref并把任何异常捕获到error中。自动连接通过watch(device, ...)监听设备变化一旦拿到设备就调用connectToBluetoothGATTServer()校验device.gatt存在后执行device.gatt.connect()得到BluetoothRemoteGATTServer存入server并用server.connected同步isConnected。组件挂载时tryOnMounted也会主动尝试连接一次。断开与清理挂载时注册gattserverdisconnected事件监听触发后执行reset()把isConnected、device、server一并清空tryOnScopeDispose则保证组件卸载时调用device.gatt?.disconnect()主动断开连接。仓库中的测试 index.browser.test.ts 验证了两个关键行为其一多次requestDevice切换设备后gattserverdisconnected监听器不会在旧设备上累积泄漏其二连接完成后server与isConnected会被正确更新模拟设备断开后状态也能正确复位。这些测试也展示了如何通过注入自定义navigator来在无真实蓝牙硬件的环境中编写单元测试。注意事项与适用前提使用useBluetooth前请务必确认以下限制它们来自文档的明确提示浏览器支持有限Web Bluetooth API 目前仅在部分平台上部分实现包括 Android M、Chrome OS、macOS 与 Windows 10。生产环境务必在 UI 上先检查isSupported再决定是否展示“请求设备”按钮。规范存在诸多坑Web Bluetooth 规范本身在设备发现与连接方面存在多种边界情况如设备缓存、连接超时、GATT 服务不可见等建议通读 W3C 草稿报告中的 caveat 说明。Web Worker 中不可用该 API 不会暴露在WorkerNavigator上因此无法在 Web Worker 环境中使用useBluetooth。必须由用户手势触发requestDevice()需要在用户点击等用户手势上下文中调用否则浏览器会拒绝弹窗。HTTPS 前提Web Bluetooth 是安全上下文 API网页必须运行在 HTTPS或 localhost环境下才能使用。小结useBluetooth把复杂的 Web Bluetooth 生命周期——能力检测、设备请求、GATT 连接、断开复位、资源清理——收敛成一组简洁的响应式状态与一个触发函数让 Vue 开发者可以像使用普通响应式变量一样操作 BLE 外设。配合useEventListener监听特征值变化你就能以极少的样板代码构建出真实的 BLE 交互应用。继续阅读本仓库的 index.md 文档 与 源码实现可以进一步探索更深层的 API 细节。赞分享前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载相关推荐AIRI 项目实战用 VueUse useBluetooth 在 Vue 3 中接入 Web Bluetooth 低功耗设备AIRI 项目实战用 VueUse useBluetooth 在 Vue 3 中接入 Web Bluetooth 低功耗设备 导读 useBluetoothAI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染VueUse useBluetooth 深度指南基于 Web Bluetooth API 的响应式 BLE 设备连接VueUse useBluetooth 深度指南基于 Web Bluetooth API 的响应式 BLE 设备连接 useBluetooth 是 VueUs前端在 Vue 3 应用中用 VueUse useDeviceOrientation 响应式接入设备方向传感器在 Vue 3 应用中用 VueUse useDeviceOrientation 响应式接入设备方向传感器 导读 useDeviceOrientation 是AI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染上一篇终极指南如何用开源工具解决艾尔登法环存档迁移难题下一篇Gun.js单元测试指南确保实时应用稳定性创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

免费获取报价 →
↑