
Storybook硬件交互串口与蓝牙组件引言在现代前端开发中与硬件设备的交互变得越来越重要。Storybook作为一个独立运行的UI组件开发环境不仅支持各种前端框架还为硬件交互组件的开发提供了便利。本文将详细介绍如何在Storybook中开发和测试串口Serial Port与蓝牙Bluetooth交互组件帮助开发者快速上手硬件交互功能。串口通信组件开发串口通信概述串口通信是一种常见的硬件通信方式广泛应用于嵌入式系统、物联网设备等领域。在前端中可以通过Web Serial API实现与串口设备的通信。Storybook提供了隔离的开发环境使得串口组件的开发和测试更加高效。串口组件示例以下是一个简单的串口通信组件示例展示了如何在Storybook中创建和使用串口组件import React, { useState, useEffect } from react; const SerialPortComponent () { const [port, setPort] useState(null); const [data, setData] useState(); const [inputValue, setInputValue] useState(); const requestPort async () { try { const port await navigator.serial.requestPort(); await port.open({ baudRate: 9600 }); setPort(port); readFromPort(port); } catch (error) { console.error(Error requesting serial port:, error); } }; const readFromPort async (port) { const reader port.readable.getReader(); while (true) { try { const { value, done } await reader.read(); if (done) break; setData(prev prev new TextDecoder().decode(value)); } catch (error) { console.error(Error reading from port:, error); break; } } reader.releaseLock(); }; const writeToPort async () { if (!port || !inputValue) return; const writer port.writable.getWriter(); await writer.write(new TextEncoder().encode(inputValue)); writer.releaseLock(); setInputValue(); }; return ( div button onClick{requestPort}连接串口/button div input typetext value{inputValue} onChange{(e) setInputValue(e.target.value)} / button onClick{writeToPort}发送数据/button /div div接收数据: {data}/div /div ); }; export default SerialPortComponent;串口组件Story编写为上述串口组件编写Story以便在Storybook中进行展示和测试import SerialPortComponent from ./SerialPortComponent; export default { title: Hardware/SerialPort, component: SerialPortComponent, }; export const Default () SerialPortComponent /;蓝牙通信组件开发蓝牙通信概述蓝牙通信是另一种常见的硬件交互方式Web Bluetooth API允许网页应用与蓝牙设备进行通信。在Storybook中开发蓝牙组件可以模拟各种蓝牙设备的交互场景提高组件的健壮性。蓝牙组件示例以下是一个蓝牙通信组件的示例代码import React, { useState } from react; const BluetoothComponent () { const [device, setDevice] useState(null); const [data, setData] useState(); const [inputValue, setInputValue] useState(); const requestDevice async () { try { const device await navigator.bluetooth.requestDevice({ acceptAllDevices: true, optionalServices: [0000ffe0-0000-1000-8000-00805f9b34fb], }); setDevice(device); connectToDevice(device); } catch (error) { console.error(Error requesting device:, error); } }; const connectToDevice async (device) { const server await device.gatt.connect(); const service await server.getPrimaryService(0000ffe0-0000-1000-8000-00805f9b34fb); const characteristic await service.getCharacteristic(0000ffe1-0000-1000-8000-00805f9b34fb); characteristic.addEventListener(characteristicvaluechanged, (event) { setData(prev prev new TextDecoder().decode(event.target.value)); }); await characteristic.startNotifications(); }; const writeToDevice async () { if (!device || !inputValue) return; try { const server await device.gatt.connect(); const service await server.getPrimaryService(0000ffe0-0000-1000-8000-00805f9b34fb); const characteristic await service.getCharacteristic(0000ffe1-0000-1000-8000-00805f9b34fb); await characteristic.writeValue(new TextEncoder().encode(inputValue)); setInputValue(); } catch (error) { console.error(Error writing to device:, error); } }; return ( div button onClick{requestDevice}连接蓝牙设备/button div input typetext value{inputValue} onChange{(e) setInputValue(e.target.value)} / button onClick{writeToDevice}发送数据/button /div div接收数据: {data}/div /div ); }; export default BluetoothComponent;蓝牙组件Story编写为蓝牙组件编写Storyimport BluetoothComponent from ./BluetoothComponent; export default { title: Hardware/Bluetooth, component: BluetoothComponent, }; export const Default () BluetoothComponent /;硬件交互组件测试测试策略在Storybook中测试硬件交互组件可以使用Mock Service WorkerMSW来模拟硬件设备的响应避免对真实硬件的依赖。测试示例使用Storybook的测试工具对串口组件进行测试import { render, screen, fireEvent } from testing-library/react; import SerialPortComponent from ./SerialPortComponent; // Mock the Web Serial API beforeEach(() { global.navigator.serial { requestPort: jest.fn().mockResolvedValue({ open: jest.fn().mockResolvedValue({}), readable: { getReader: jest.fn().mockReturnValue({ read: jest.fn().mockResolvedValue({ value: new TextEncoder().encode(Test data), done: false }), releaseLock: jest.fn(), }), }, writable: { getWriter: jest.fn().mockReturnValue({ write: jest.fn().mockResolvedValue(), releaseLock: jest.fn(), }), }, }), }; }); test(connects to serial port and reads data, async () { render(SerialPortComponent /); fireEvent.click(screen.getByText(连接串口)); expect(global.navigator.serial.requestPort).toHaveBeenCalled(); // Wait for data to be read await new Promise(resolve setTimeout(resolve, 100)); expect(screen.getByText(/接收数据: Test data/)).toBeInTheDocument(); });总结本文介绍了如何在Storybook中开发和测试串口与蓝牙通信组件。通过Storybook的隔离环境和丰富的插件生态可以大大提高硬件交互组件的开发效率和质量。开发者可以根据实际需求进一步扩展组件功能如添加数据可视化、错误处理等。官方文档docs/writing-stories/ 组件示例源码code/sandbox/ 测试工具code/addons/vitest/创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考