当前位置: 首页 > java >正文

数据共享的艺术

UniApp全局状态管理宝典:数据共享的艺术

为什么需要全局状态管理?

想象你的应用是一个繁忙的公司,不同部门(组件)需要共享和更新同一份文件(数据)。如果没有集中管理,就会出现数据混乱、版本冲突和沟通困难的问题。

┌──────────────────────────────────────────────────────┐
│             没有全局状态管理的混乱                   │
│                                                      │
│    组件A        组件B         组件C        组件D     │
│      │            │            │            │        │
│      ▼            ▼            ▼            ▼        │
│   ┌─────┐      ┌─────┐      ┌─────┐      ┌─────┐    │
│   │状态A│      │状态B│      │状态C│      │状态D│    │
│   └─────┘      └─────┘      └─────┘      └─────┘    │
│      ↓            ↑            ↓            ↑        │
│      └────────────┘            └────────────┘        │
│             混乱的数据同步                           │
│                                                      │
└──────────────────────────────────────────────────────┘

UniApp全局状态管理的五大方式

1. Vuex/Pinia:正规军的数据管理中心

Vuex和Pinia就像一个中央档案馆,所有数据变更都必须登记备案,并由专人(mutations/actions)处理,确保数据的安全与一致。

生活类比:中央银行系统

Vuex就像一个国家的中央银行系统:

  • 金库(state) - 集中存储所有资金
  • 出纳员(mutations) - 负责资金存取,记录每笔交易
  • 银行经理(actions) - 处理复杂业务,可能涉及多项交易
  • 会计(getters) - 计算资产状况,生成财务报表
  • 分行网点(modules) - 处理不同区域或业务线的独立账务
┌──────────────────────────────────────────────────────┐
│                  Vuex数据流向图                      │
│                                                      │
│  ┌───────────┐       ┌───────────┐                  │
│  │   视图    │──────►│  Actions  │                  │
│  │ Components│       └─────┬─────┘                  │
│  └─────┬─────┘             │                        │
│        │                   ▼                        │
│        │             ┌───────────┐                  │
│        │             │ Mutations │                  │
│        │             └─────┬─────┘                  │
│        │                   │                        │
│        │                   ▼                        │
│        │             ┌───────────┐    ┌──────────┐  │
│        │◄────────────│   State   │◄───│ Getters  │  │
│        │             └───────────┘    └──────────┘  │
│        │                   ▲                        │
│        └───────────────────┘                        │
│                                                      │
└──────────────────────────────────────────────────────┘
代码示例:设置Vuex
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {// 用户信息userInfo: null,// 购物车cartItems: [],// 应用设置appSettings: {theme: 'light',fontSize: 'medium'}},getters: {// 计算购物车总金额cartTotal(state) {return state.cartItems.reduce((total, item) => {return total + (item.price * item.quantity)}, 0)},// 判断用户是否登录isLoggedIn(state) {return state.userInfo !== null}},mutations: {// 更新用户信息SET_USER_INFO(state, userInfo) {state.userInfo = userInfo},// 添加商品到购物车ADD_TO_CART(state, product) {const existItem = state.cartItems.find(item => item.id === product.id)if (existItem) {existItem.quantity++} else {state.cartItems.push({...product,quantity: 1})}},// 更新应用设置UPDATE_SETTINGS(state, settings) {state.appSettings = {...state.appSettings,...settings}}},actions: {// 异步登录操作async login({ commit }, credentials) {try {// 调用登录APIconst response = await uni.request({url: 'https://api.example.com/login',method: 'POST',data: credentials})// 保存用户信息commit('SET_USER_INFO', response.data.userInfo)// 存储tokenuni.setStorageSync('token', response.data.token)return response.data} catch (error) {console.error('登录失败', error)throw error}},// 异步加载购物车async loadCart({ commit }) {try {const token = uni.getStorageSync('token')if (!token) returnconst response = await uni.request({url: 'https://api.example.com/cart',header: { Authorization: `Bearer ${token}` }})// 更新购物车response.data.items.forEach(item => {commit('ADD_TO_CART', item)})} catch (error) {console.error('加载购物车失败', error)}}},// 分模块管理不同功能的状态modules: {products: {namespaced: true,state: {list: [],categories: []},mutations: {SET_PRODUCTS(state, products) {state.list = products}}}}
})
使用Vuex的组件示例
<template><view class="container"><!-- 显示用户信息 --><view class="user-info" v-if="isLoggedIn"><text>欢迎回来,{{ userInfo.nickname }}</text></view><button v-else @tap="handleLogin">登录</button><!-- 购物车信息 --><view class="cart-info"><text>购物车: {{ cartItems.length }}件商品</text><text>总计: ¥{{ cartTotal }}</text></view><!-- 主题设置 --><view class="settings"><text>当前主题: {{ appSettings.theme }}</text><button @tap="toggleTheme">切换主题</button></view></view>
</template><script>
import { mapState, mapGetters, mapActions } from 'vuex'export default {computed: {// 映射state到计算属性...mapState(['userInfo', 'cartItems', 'appSettings']),// 映射getters到计算属性...mapGetters(['isLoggedIn', 'cartTotal'])},methods: {// 映射actions到方法...mapActions(['login', 'loadCart']),async handleLogin() {try {await this.login({username: 'testuser',password: 'password123'})uni.showToast({title: '登录成功'})// 登录成功后加载购物车this.loadCart()} catch (error) {uni.showToast({title: '登录失败',icon: 'none'})}},toggleTheme() {// 切换主题const newTheme = this.appSettings.theme === 'light' ? 'dark' : 'light'this.$store.commit('UPDATE_SETTINGS', { theme: newTheme })}},onLoad() {// 页面加载时检查用户状态if (uni.getStorageSync('token')) {this.loadCart()}}
}
</script>

2. Uni.storage:简单而持久的数据仓库

当需要在应用重启后仍保留数据状态时,可以使用uni.storage API将数据存储在本地。

生活类比:保险柜

Uni.storage就像你家的保险柜:

  • 适合存放重要但不常取用的物品(数据)
  • 即使停电(应用关闭),物品也安全保存
  • 取放操作较慢,不适合频繁操作
  • 空间有限,不能存放过大的物品
┌──────────────────────────────────────────────────────┐
│                 Storage工作流程                       │
│                                                      │
│  ┌───────────┐   存储   ┌───────────┐               │
│  │ 应用数据  │─────────►│本地存储区 │               │
│  │           │◄─────────│           │               │
│  └───────────┘   读取   └───────────┘               │
│        │                      │                      │
│        │                      │                      │
│        ▼                      ▼                      │
│  ┌───────────┐          ┌───────────┐               │
│  │ 应用关闭  │          │ 设备重启  │               │
│  └───────────┘          └───────────┘               │
│        │                      │                      │
│        │                      │                      │
│        ▼                      ▼                      │
│        └──────────数据依然保留──────────┘            │
│                                                      │
└──────────────────────────────────────────────────────┘
代码示例:封装Storage状态管理器
// utils/storageManager.js
class StorageManager {constructor(namespace = 'app') {this.namespace = namespacethis.memoryState = this.loadState()// 监听应用退出时保存状态// #ifdef APP-PLUSplus.runtime.addEventListener('quit', () => {this.saveState()})// #endif}// 加载状态loadState() {try {const stateJSON = uni.getStorageSync(`${this.namespace}_state`)return stateJSON ? JSON.parse(stateJSON) : this.getInitialState()} catch (error) {console.error('加载状态失败', error)return this.getInitialState()}}// 保存状态saveState() {try {uni.setStorageSync(`${this.namespace}_state`, JSON.stringify(this.memoryState))} catch (error) {console.error('保存状态失败', error)}}// 初始状态getInitialState() {return {userInfo: null,settings: {theme: 'light',language: 'zh-CN'},history: [],favorites: []}}// 获取整个状态getState() {return this.memoryState}// 获取特定键的值get(key) {return key.split('.').reduce((obj, k) => {return obj && obj[k] !== undefined ? obj[k] : null}, this.memoryState)}// 设置特定键的值set(key, value) {const keys = key.split('.')const lastKey = keys.pop()const target = keys.reduce((obj, k) => {if (obj[k] === undefined) obj[k] = {}return obj[k]}, this.memoryState)target[lastKey] = valuethis.saveState() // 保存到存储return value}// 特定功能方法setUserInfo(userInfo) {this.set('userInfo', userInfo)}addToFavorites(item) {const favorites = this.get('favorites') || []if (!favorites.some(i => i.id === item.id)) {favorites.push(item)this.set('favorites', favorites)}}removeFromFavorites(itemId) {let favorites = this.get('favorites') || []favorites = favorites.filter(item => item.id !== itemId)this.set('favorites', favorites)}// 清除所有状态clearState() {this.memoryState = this.getInitialState()this.saveState()}
}// 创建并导出单例实例
export const stateManager = new StorageManager()
使用StorageManager的组件示例
<template><view class="settings-page"><view class="setting-item"><text>主题</text><picker :value="themeIndex" :range="themes" @change="changeTheme"><view class="picker-value">{{ themes[themeIndex] }}</view></picker></view><view class="setting-item"><text>语言</text><picker :value="languageIndex" :range="languages" range-key="name"@change="changeLanguage"><view class="picker-value">{{ languages[languageIndex].name }}</view></picker></view><view class="favorites"><text class="section-title">我的收藏 ({{ favorites.length }})</text><view v-for="(item, index) in favorites" :key="index"class="favorite-item"><text>{{ item.name }}</text><button @tap="removeFavorite(item.id)" size="mini" type="warn">删除</button></view></view><button @tap="clearAll" type="warn">清除所有数据</button></view>
</template><script>
import { stateManager } from '@/utils/storageManager.js'export default {data() {return {themes: ['light', 'dark', 'auto'],themeIndex: 0,languages: [{ code: 'zh-CN', name: '简体中文' },{ code: 'en-US', name: 'English' }],languageIndex: 0,favorites: []}},onShow() {// 加载设置和收藏this.loadSettings()this.loadFavorites()},methods: {loadSettings() {const settings = stateManager.get('settings')if (settings) {// 找到主题索引this.themeIndex = this.themes.findIndex(t => t === settings.theme)
http://www.xdnf.cn/news/7143.html

相关文章:

  • C++中的容器
  • 进程和线程的区别和联系
  • FreeRTOS的学习记录(中断管理)
  • 5.18打卡
  • 延时双删-争议与我的思路-001
  • 动态通讯录程序
  • P1009 [NOIP 1998 普及组] 阶乘之和
  • 深入理解 LangChain 文档处理机制:Document 类与文档加载器详解
  • uni-app学习笔记七-vue3事件处理
  • 优化 Spring Boot 应用启动性能的实践指南
  • 单片机超频怎么搞?
  • 实时时钟项目设计
  • 腾讯云证书过期提醒的应对措施,Caddy 自动管理的 Let‘s Encrypt 证书.
  • 使用国内源加速Qt在线安装
  • Docker拉取镜像报错Error response from daemon: Get “https://registry-1.docker.io/v2/“
  • 测试--测试分类 (白盒 黑盒 单元 集成)
  • vscode中Debug c++
  • Android开发-列表类视图
  • 亚马逊新品3周冲刺BSR前10:数据驱动的冷启动破局指南
  • 模型评估与调优(PyTorch)
  • 四品种交易策略
  • MetaMask安装及使用-使用水龙头获取测试币的坑?
  • C++ThreadPool
  • 回溯实战篇3
  • 新电脑软件配置二:安装python,git, pycharm
  • 2025年PMP 学习二十 第13章 项目相关方管理
  • docker-compose部署项目(springboot服务)以及基础环境(mysql、redis等)ruoyi-ry
  • 【数字电路】第七章 脉冲波形的产生与整形电路
  • 【推荐】新准则下对照会计报表172个会计科目解释
  • Gartner《如何将生成式人工智能(GenAI)集成到应用架构》学习心得