毕设日志26.4.2(2):HBuilderX开发蓝牙时钟APP,全局状态管理之全局声明完毕后管理模块代码中的全局变量

张开发
2026/4/12 13:22:40 15 分钟阅读

分享文章

毕设日志26.4.2(2):HBuilderX开发蓝牙时钟APP,全局状态管理之全局声明完毕后管理模块代码中的全局变量
在前文中我们完成了全局状态管理的声明部分成功将一些变量和函数修改为了全局变量和全局函数。现在任务是把原本的单模块里的变量和代码修改成全局的形式。Q原本我们修改某些变量的方式是this.isInit true;现在应该是this.$store.commit(SET_INIT, true)但原本单模块被拆分为多模块后里面还保留了单模块变量的定义和声明。这些不用删掉吗A要删。Q怎么删改详细说说A具体操作步骤1. 在bluetooth.vue中添加computed映射javascriptcomputed: { isSupported() { return this.$store.state.isSupported }, isInit() { return this.$store.state.isInit }, isScanning() { return this.$store.state.isScanning }, devicesList() { return this.$store.state.devicesList }, connectedDeviceId() { return this.$store.state.connectedDeviceId }, serviceId() { return this.$store.state.serviceId }, rxCharacteristicId() { return this.$store.state.rxCharacteristicId }, txCharacteristicId() { return this.$store.state.txCharacteristicId }, lastReply() { return this.$store.state.lastReply } }2. 删除data()中的这些属性原来的data里只保留组件内部不需要全局共享的临时变量如果有的话但你这里所有状态都已全局化所以可以清空data或只留空对象。3. 修改所有this.xxx ...为this.$store.commit(...)在methods中所有原本直接赋值this.isInit true的地方都要改成this.$store.commit(SET_INIT_STATUS, true)。其他类似this.isScanning true→commit(SET_SCANNING, true)this.devicesList.push(device)→ 需要先获取当前数组提交新的数组因为 mutation 要替换整个数组不能直接 pushthis.connectedDeviceId deviceId→commit(SET_CONNECTED_DEVICE, deviceId)this.lastReply data→commit(SET_LAST_REPLY, data)4. 在store/index.js中补充缺失的 mutations 和 state确保state包含上述所有字段并添加对应的 mutation例如javascriptSET_SCANNING(state, status) { state.isScanning status }, SET_DEVICES_LIST(state, list) { state.devicesList list }, // 注意数组要整体替换不能直接 push5. 删除全局事件总线uni.$emit(ble-reply, data)可选因为现在所有页面都从 Vuex 读取lastReply不需要再手动广播。为什么不删会导致问题如果你不删除data中的同名变量那么组件会同时拥有两份数据一份在 Vuex 中通过computed映射一份在组件自身的data中被模板直接使用当你调用this.$store.commit修改 Vuex 状态时组件的computed会更新但如果你在模板中绑定的是data中的变量比如{{ isInit }}由于你没有修改this.isInit它不会变。如果你已经删除了data中的定义那么模板中的isInit就会自动去computed中找从而使用 Vuex 的值。所以必须删除data中的同名属性让模板绑定到computed上。Q不太明白。computed是什么而且如果把那些删除了那么 SET_CONNECTED_DEVICE(state, deviceId)里的deviceId用什么装不是还要在模板里面创建一个变量装deviceId然后再传给commit里的函数吗A一、computed是什么computed是 Vue 组件中的一个配置项用于定义计算属性。计算属性是一个函数它的返回值会作为组件的属性被模板使用并且当它依赖的响应式数据例如this.$store.state.xxx发生变化时它会自动重新计算。通俗理解computed就是告诉 Vue“我需要一个叫connectedDeviceId的值它的内容是从this.$store.state.connectedDeviceId读来的你帮我实时跟踪这个值的变化。”解读意思是connectedDeviceId 原本是data里面的一个我定义的变量现在如果它是全局的就不在data里面定义了而是在computed里写一个函数这个函数在作用上就等价于全局变量声明拥有追踪变量变化的功能。二、为什么要用computed而不是直接在data中存一份如果你在data中存connectedDeviceId: 然后在蓝牙连接成功后执行this.connectedDeviceId deviceId这个值只在这个组件内部有效。其他组件不知道它变了。如果你用 Vuex 存储connectedDeviceId并在组件中用computed去读取它那么这个组件会自动“订阅” Vuex 中的connectedDeviceId。当任何地方commit(SET_CONNECTED_DEVICE, newId)后所有读取这个值的组件的计算属性都会重新求值模板自动更新。简单说computed是把 Vuex 中的数据“映射”到组件里让模板可以用简洁的变量名访问并且保持响应式。解读其实作用就是及时更新。vuex框架下全局变量的固定格式只有这样才能同步变量变化仅此而已。三、你问的“deviceId 用什么装”在connectDevice方法中你从蓝牙 API 的回调里拿到了一个参数deviceId字符串。这个字符串本身就是一个局部变量不需要额外“装”它。你需要做的是把这个值提交给 Vuex让 Vuex 存起来。原来的代码javascriptconnectDevice(deviceId) { uni.createBLEConnection({ deviceId: deviceId, success: (res) { this.connectedDeviceId deviceId // 存在组件 data 中 } }) }改成javascriptconnectDevice(deviceId) { uni.createBLEConnection({ deviceId: deviceId, success: (res) { this.$store.commit(SET_CONNECTED_DEVICE, deviceId) // 存在 Vuex 中 } }) }此时deviceId这个值被传给了 mutationmutation 会把它保存到state.connectedDeviceId中。之后任何组件如果需要显示或判断连接状态就通过computed读取this.$store.state.connectedDeviceId。四、模板里的connectedDeviceId现在从哪里来模板中原来写的是v-ifconnectedDeviceId这个connectedDeviceId原本是data里的变量。现在你删除了data中的connectedDeviceId但模板里依然要用所以需要在computed中提供一个同名的计算属性javascriptcomputed: { connectedDeviceId() { return this.$store.state.connectedDeviceId } }这样模板中的connectedDeviceId实际上就是读取 Vuex 中的值。五、总结computed的作用从 Vuex 的 state 中读取数据并暴露给模板使用同时保持响应式。deviceId不需要在组件 data 中装直接作为参数提交给 mutation 即可。删除 data 中的变量后必须用computed映射同名属性否则模板会找不到变量。如果你还不清楚computed的语法或工作原理我可以写一个最简单的 Vue 示例不涉及蓝牙让你感受一下。所以接下来的工作就是所以就是把data里的变量改了加上computed然后再把函数的调用还有值的删改改一改。

更多文章