Files
akmon/pages/sense/DEVICE_STORE_GUIDE.md
2026-01-20 08:04:15 +08:00

6.3 KiB
Raw Permalink Blame History

设备状态管理 (Device Store) 使用指南

概述

为了避免在不同模块中重复请求设备数据,我们将设备信息集中管理在全局状态中。这样可以:

  • 提高性能:避免重复的网络请求
  • 数据一致性:所有模块共享同一份设备数据
  • 实时更新设备状态变更时所有相关UI自动更新
  • 缓存机制智能缓存5分钟内不重复请求
  • 简化代码统一的设备操作API

核心功能

1. 设备状态管理

// 设备状态类型
export type DeviceState = {
	devices: Array<DeviceInfo>        // 设备列表
	currentDevice: DeviceInfo | null  // 当前选中设备
	isLoading: boolean               // 加载状态
	lastUpdated: number | null       // 最后更新时间
}

2. 主要API方法

获取设备信息

const deviceStore = getDeviceStore()

// 获取所有设备
const devices = deviceStore.getDevices()

// 获取当前设备
const currentDevice = deviceStore.getCurrentDevice()

// 根据ID获取设备
const device = deviceStore.getDeviceById('device_id')

// 获取在线设备
const onlineDevices = deviceStore.getOnlineDevices()

设备操作

// 加载设备列表(带缓存,不强制刷新)
await deviceStore.refreshDevices()

// 强制刷新设备列表(忽略缓存)
await deviceStore.loadDevices(true)

// 绑定新设备
const success = await deviceStore.bindDevice(deviceData)

// 解绑设备
const success = await deviceStore.unbindDevice(deviceId)

// 更新设备配置
const success = await deviceStore.updateDevice(deviceId, configData)

// 设置当前设备
deviceStore.setCurrentDevice(device)

状态查询

// 获取加载状态
const isLoading = deviceStore.isLoading()

// 获取最后更新时间
const lastUpdated = deviceStore.getLastUpdated()

在Vue组件中的使用

1. 基本使用

<template>
	<view>
		<!-- 显示设备列表 -->
		<view v-if="isLoading">加载中...</view>
		<view v-else>
			<view v-for="device in devices" :key="device.id">
				{{ device.device_name }}
			</view>
		</view>
	</view>
</template>

<script lang="uts">
import { computed, onMounted } from 'vue'
import { getDeviceStore } from '@/utils/store.uts'

export default {
	setup() {
		const deviceStore = getDeviceStore()
		
		// 响应式数据
		const devices = computed(() => deviceStore.getDevices())
		const isLoading = computed(() => deviceStore.isLoading())
		
		// 页面挂载时加载设备
		onMounted(async () => {
			await deviceStore.loadDevices()
		})
		
		return {
			devices,
			isLoading
		}
	}
}
</script>

2. 设备管理页面

// 设备管理操作
const bindDevice = async (deviceData: UTSJSONObject) => {
	const success = await deviceStore.bindDevice(deviceData)
	if (success) {
		// 设备已自动添加到storeUI自动更新
		uni.showToast({ title: '绑定成功' })
	}
}

const unbindDevice = async (deviceId: string) => {
	const success = await deviceStore.unbindDevice(deviceId)
	if (success) {
		// 设备已自动从store移除UI自动更新
		uni.showToast({ title: '解绑成功' })
	}
}

3. 跨页面设备状态共享

// 页面A选择设备
const selectDevice = (device: DeviceInfo) => {
	deviceStore.setCurrentDevice(device)
	uni.navigateTo({
		url: `/pages/sense/detail?device_id=${device.id}`
	})
}

// 页面B使用选中的设备
const currentDevice = computed(() => deviceStore.getCurrentDevice())
// currentDevice 会自动包含页面A选择的设备信息

缓存机制

设备数据具有智能缓存机制:

  • 自动缓存首次加载后数据会被缓存5分钟
  • 避免重复请求5分钟内的 loadDevices() 调用直接返回缓存数据
  • 强制刷新:使用 loadDevices(true) 可以强制从服务器重新获取
  • 实时更新:设备操作(绑定、解绑、更新)会实时更新缓存

文件结构

utils/
  store.uts                    # 主要的store文件包含设备状态管理
  
pages/sense/
  devices.uvue                 # 设备管理页面已更新使用store
  index.uvue                   # 传感器主页已更新使用store
  detail.uvue                  # 设备详情页
  senseDataService.uts         # 设备数据服务
  deviceStoreExample.uts       # 使用示例和最佳实践
  insertExample.uts            # 插入操作示例

优势

性能优化

  • 减少网络请求:避免重复的设备列表请求
  • 智能缓存5分钟内复用数据
  • 按需更新:只在必要时刷新数据

开发体验

  • 统一API所有设备操作通过同一个接口
  • 类型安全完整的TypeScript类型支持
  • 响应式Vue的响应式系统自动更新UI
  • 错误处理:统一的错误处理和用户反馈

数据一致性

  • 单一数据源:所有模块共享同一份设备数据
  • 实时同步:设备状态变更立即反映到所有页面
  • 状态持久:页面间跳转不丢失设备状态

迁移指南

如果现有页面直接使用 SenseDataService

原来的代码:

// 旧方式:直接调用服务
const result = await SenseDataService.getDevicesByUser(userId)
if (result.success) {
	devices.value = result.data
}

更新后的代码:

// 新方式使用store
const deviceStore = getDeviceStore()
const devices = computed(() => deviceStore.getDevices())

onMounted(async () => {
	await deviceStore.refreshDevices() // 智能缓存加载
})

// 强制刷新(忽略缓存)
const forceRefresh = async () => {
	await deviceStore.loadDevices(true)
}

通过这种方式,设备状态管理变得更加高效和便于维护!

API 参考

设备加载方法

由于UTS不支持匿名函数的默认参数我们提供了两个加载方法

// 1. 智能缓存加载(推荐用于页面初始化)
await deviceStore.refreshDevices()
// 等同于 loadDevices(false),会检查缓存

// 2. 明确指定是否强制刷新
await deviceStore.loadDevices(true)   // 强制刷新,忽略缓存
await deviceStore.loadDevices(false)  // 使用缓存(如果可用)

使用建议

  • 页面初始化:使用 refreshDevices()
  • 用户手动刷新:使用 loadDevices(true)
  • 定期更新:使用 loadDevices(false)