UniApp缓存系统详解

一、UniApp 缓存系统概述

1.1 缓存概念与作用

在 UniApp 中,本地缓存(Storage)是一种键值对(Key-Value)存储机制,用于在设备本地保存小量数据。它类似于浏览器的 localStorage 或小程序的 wx.setStorage,但 UniApp 通过统一的 API 封装,实现了跨平台的透明使用。缓存的作用主要体现在以下方面:

  • 性能提升:避免重复网络请求。例如,登录后将 Token 存入缓存,下次启动 App 时直接读取,无需重新验证。
  • 用户体验优化:支持离线模式,如缓存文章列表,用户无网也能浏览。
  • 数据持久化:应用重启或页面刷新后,数据不丢失(除非手动清理)。
  • 状态共享:跨页面/组件共享数据,如购物车内容。

与内存状态(如 Vuex)不同,缓存是持久化的,但需注意其非关系型特性:不支持复杂查询,仅适合简单对象或字符串。在实际项目中,我经常用它来处理临时配置,避免每次启动都从服务器拉取。

1.2 平台差异详解

UniApp 缓存在不同平台的底层实现有所差异,这直接影响存储上限、持久性和清理策略。以下表格总结关键差异:

平台 底层实现 存储上限 持久性 清理机制
H5 localStorage 约 5MB(浏览器限制) 缓存概念,可能被浏览器清理 用户清除浏览数据或过期
App plus.storage 无限制(设备存储空间) 持久化,直至卸载 App 手动清理或系统空间不足
微信小程序 wx.setStorage 单 key 1MB,总 10MB 与小程序生命周期绑定 用户删除小程序或超限自动清理
支付宝小程序 my.setStorage 单条 200KB,总 10MB 与小程序生命周期绑定 超限自动清理
百度/抖音小程序 平台特定 API 视平台文档(约 10MB) 与小程序生命周期绑定 平台策略清理
HarmonyOS 分布式存储 视设备(HBuilderX 4.23+ 支持) 持久化 手动或系统管理

注意 :清空缓存后,非 App 平台可能导致 uni.getSystemInfo 的 deviceId 改变,影响设备标识。开发者需在多端测试,确保兼容。在我的经验中,App 端的无限制存储特别适合缓存大文件列表,但要警惕设备空间耗尽。

1.3 支持的数据类型与限制

UniApp 缓存支持原生类型(String、Number、Boolean、Array、Object)和可通过 JSON.stringify 序列化的复杂对象。但不支持函数、Date 对象(需转为字符串)或循环引用。限制包括:

  • Key 命名 :避免系统保留前缀(如 uni-dcloud_),否则可能冲突或失败。
  • 数据大小:超出平台上限时,存储失败,无自动压缩。
  • 线程安全:异步 API 不阻塞 UI 线程,同步 API 可能在高频操作时影响性能。
  • 生命周期:H5/App 持久,小程序随应用销毁。

这些基础认知是上手的关键,接下来我们深入 API 层面。

二、基础 API 详解

UniApp 提供 5 对核心 API:存储、获取、移除、清空和信息查询。每对均有异步(回调式)和同步(try-catch 式)版本。异步适合复杂场景,避免阻塞;同步适合简单操作,代码简洁。以下逐一拆解。

2.1 存储数据:uni.setStorage / uni.setStorageSync

原理:将数据存入指定 key,会覆盖原有内容。底层序列化为字符串存储。

异步版本:uni.setStorage(OBJECT)

参数表:

参数名 类型 必填 说明
key String 缓存键名,建议使用描述性命名如 'user_token'
data Any 存储内容,支持 JSON 序列化对象
success Function 成功回调,无参数
fail Function 失败回调,参数为错误对象
complete Function 结束回调,无论成败

返回值:无,通过回调处理。

示例(Vue 页面中):

javascript 复制代码
// pages/index/index.vue
export default {
  methods: {
    asyncStoreData() {
      uni.setStorage({
        key: 'user_info',
        data: { id: 1, name: '张三', token: 'abc123' },
        success: () => {
          console.log('存储成功');
          uni.showToast({ title: '数据已缓存' });
        },
        fail: (err) => {
          console.error('存储失败:', err);
          uni.showToast({ title: '存储出错', icon: 'none' });
        }
      });
    }
  }
}

解释:在按钮点击事件中调用,成功后提示用户。data 对象自动序列化。在实际开发中,这种异步方式特别适合用户交互密集的页面。

同步版本:uni.setStorageSync(key, data)

参数:key (String,必填),data (Any,必填)。

返回值:无,使用 try-catch 处理异常。

示例:

javascript 复制代码
try {
  uni.setStorageSync('user_info', { id: 1, name: '张三', token: 'abc123' });
  console.log('同步存储成功');
} catch (e) {
  console.error('同步存储失败:', e);
}

规则

  • 异步优先:UI 交互场景用异步,避免卡顿。
  • 错误处理:fail 回调捕获网络/权限问题,try-catch 捕获序列化失败。
  • 注意事项:data 必须可序列化,否则抛错(如包含函数)。我通常在存储前添加一个序列化检查函数,确保稳定性。

2.2 获取数据:uni.getStorage / uni.getStorageSync

原理:从 key 读取内容,若不存在返回 undefined 或空值。

异步版本:uni.getStorage(OBJECT)

参数表:

参数名 类型 必填 说明
key String 缓存键名
success Function 回调,res = { data: 读取内容 }
fail Function 失败回调
complete Function 结束回调

success 返回值:{ data: Any }

示例:

javascript 复制代码
asyncGetData() {
  uni.getStorage({
    key: 'user_info',
    success: (res) => {
      if (res.data) {
        console.log('获取数据:', res.data.name);
        this.userName = res.data.name;  // 更新页面数据
      } else {
        console.log('缓存为空');
      }
    },
    fail: (err) => {
      console.error('获取失败:', err);
    }
  });
}

解释:读取后直接绑定到页面 data,实现响应式更新。在组件 mounted 钩子中调用,能快速初始化视图。

同步版本:uni.getStorageSync(key)

参数:key (String,必填)。

返回值:Any(不存在时 undefined)。

示例:

javascript 复制代码
try {
  const userInfo = uni.getStorageSync('user_info');
  if (userInfo) {
    console.log('同步获取:', userInfo.name);
  } else {
    console.log('无数据');
  }
} catch (e) {
  console.error('同步获取失败:', e);
}

规则

  • 默认值处理:读取前可检查 typeof res.data !== 'undefined'。
  • 性能提示:高频读取用同步,低频用异步。同步版本在初始化阶段特别高效,能节省几毫秒加载时间。

2.3 移除数据:uni.removeStorage / uni.removeStorageSync

原理:删除指定 key,若不存在仍返回成功。

异步版本:uni.removeStorage(OBJECT)

参数表:

参数名 类型 必填 说明
key String 要移除的键名
success Function 成功回调,无参数
fail Function 失败回调
complete Function 结束回调

示例:

javascript 复制代码
removeData() {
  uni.removeStorage({
    key: 'user_info',
    success: () => {
      console.log('移除成功');
      uni.showToast({ title: '缓存已清除' });
    }
  });
}

同步版本:uni.removeStorageSync(key)

示例:

javascript 复制代码
try {
  uni.removeStorageSync('user_info');
  console.log('同步移除成功');
} catch (e) {
  console.error('移除失败:', e);
}

注意事项:移除后,相关页面需刷新数据源,避免显示旧值。结合事件总线,能通知其他组件更新。

2.4 清空数据:uni.clearStorage / uni.clearStorageSync

原理:移除所有缓存键值对,慎用!

异步版本:uni.clearStorage(OBJECT)

参数:success/fail/complete(可选)。

示例:

javascript 复制代码
clearAll() {
  uni.clearStorage({
    success: () => {
      console.log('全部清空成功');
      // 跳转登录页
      uni.reLaunch({ url: '/pages/login/login' });
    }
  });
}

同步版本:uni.clearStorageSync()

示例:

javascript 复制代码
try {
  uni.clearStorageSync();
  console.log('同步清空成功');
} catch (e) {
  console.error('清空失败:', e);
}

规则

  • 备份重要数据:清空前用 getStorageInfo 导出 keys。
  • 平台影响:非 App 端可能重置 deviceId。在生产环境中,我会添加确认对话框,防止误操作。

2.5 获取存储信息:uni.getStorageInfo / uni.getStorageInfoSync

原理:查询当前缓存状态,用于监控和调试。

异步版本:uni.getStorageInfo(OBJECT)

success 返回值:

参数名 类型 说明
keys Array 所有键名数组
currentSize Number 当前占用 KB
limitSize Number 限制 KB

示例:

javascript 复制代码
getInfo() {
  uni.getStorageInfo({
    success: (res) => {
      console.log('键列表:', res.keys);
      console.log('占用:', res.currentSize + 'KB / ' + res.limitSize + 'KB');
    }
  });
}

同步版本:uni.getStorageInfoSync()

示例:

javascript 复制代码
try {
  const res = uni.getStorageInfoSync();
  console.table(res);  // 表格输出
} catch (e) {
  console.error(e);
}

应用:在设置页显示存储使用率,提示用户清理。定期调用能帮助诊断内存问题。

通过这些基础 API,开发者可快速实现简单缓存。接下来,我们探讨如何在复杂场景中扩展它们。

三、高级用法与技巧

基础 API 虽强大,但实际项目中需处理过期、集成和安全等问题。本节提供一些实用技巧,帮助你构建更robust的缓存系统。

3.1 缓存过期机制实现

原理:UniApp 无内置过期,需手动添加时间戳判断。

实现步骤:

  1. 存储时附加 timestamp: Date.now()。
  2. 读取时计算差值,超阈值则移除并返回 null。

示例(工具函数):

javascript 复制代码
// utils/cache.js
const CACHE_EXPIRE = 60 * 60 * 1000;  // 1小时

export function setWithExpire(key, data, expire = CACHE_EXPIRE) {
  const cacheObj = {
    data,
    timestamp: Date.now() + expire
  };
  try {
    uni.setStorageSync(key, JSON.stringify(cacheObj));
  } catch (e) {
    console.error('设置过期缓存失败:', e);
  }
}

export function getWithExpire(key) {
  try {
    const str = uni.getStorageSync(key);
    if (!str) return null;
    const cacheObj = JSON.parse(str);
    if (Date.now() > cacheObj.timestamp) {
      uni.removeStorageSync(key);  // 过期移除
      return null;
    }
    return cacheObj.data;
  } catch (e) {
    console.error('获取过期缓存失败:', e);
    return null;
  }
}

使用

javascript 复制代码
// 存储
setWithExpire('article_list', articles, 30 * 60 * 1000);  // 30分钟

// 读取
const articles = getWithExpire('article_list');
if (articles) {
  this.list = articles;
} else {
  // 从服务器重新获取
}

优势:防止陈旧数据,提升数据新鲜度。在电商 App 中,我用它缓存商品价格,过期后自动刷新,避免用户看到过时信息。

3.2 与 Vuex/Pinia 集成持久化

原理:Vuex 内存状态非持久,结合缓存实现重启恢复。

Vuex 示例(store/index.js):

javascript 复制代码
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    user: null,
    cart: []
  },
  mutations: {
    SET_USER(state, user) {
      state.user = user;
      // 持久化
      uni.setStorageSync('vuex_user', JSON.stringify(user));
    },
    SET_CART(state, cart) {
      state.cart = cart;
      uni.setStorageSync('vuex_cart', JSON.stringify(cart));
    }
  },
  actions: {
    initFromCache({ commit }) {
      // 应用启动时恢复
      const userStr = uni.getStorageSync('vuex_user');
      if (userStr) commit('SET_USER', JSON.parse(userStr));
      
      const cartStr = uni.getStorageSync('vuex_cart');
      if (cartStr) commit('SET_CART', JSON.parse(cartStr));
    }
  }
});

export default store;

main.js 中调用

javascript 复制代码
import store from './store';
Vue.prototype.$store = store;
store.dispatch('initFromCache');  // App 启动时执行

Pinia 变体:类似,使用 defineStore 的 persist 插件(社区扩展)。

规则:仅持久关键状态,避免缓存大对象。在大型项目中,这种集成能让状态管理更可靠,用户重启 App 后无缝继续。

3.3 全局缓存管理工具封装

原理:统一入口,简化多处调用,支持命名空间。

示例(utils/storageManager.js):

javascript 复制代码
class StorageManager {
  constructor(namespace = '') {
    this.namespace = namespace ? `${namespace}_` : '';
  }
  
  set(key, data) {
    try {
      uni.setStorageSync(this.namespace + key, data);
    } catch (e) {
      throw new Error(`存储失败: ${e.message}`);
    }
  }
  
  get(key, defaultValue = null) {
    try {
      return uni.getStorageSync(this.namespace + key) || defaultValue;
    } catch (e) {
      console.warn(`获取失败: ${key}`);
      return defaultValue;
    }
  }
  
  remove(key) {
    try {
      uni.removeStorageSync(this.namespace + key);
    } catch (e) {}
  }
  
  clear() {
    try {
      uni.clearStorageSync();
    } catch (e) {}
  }
  
  getInfo() {
    try {
      return uni.getStorageInfoSync();
    } catch (e) {
      return null;
    }
  }
}

// 使用
const userStorage = new StorageManager('user');
userStorage.set('token', 'xyz');
const token = userStorage.get('token');

优势:避免 key 冲突,支持模块化(如 'user_token')。在团队开发中,这样的封装能减少代码重复,提高维护性。

3.4 数据加密存储

原理:敏感数据(如 Token)易被逆向,需 AES 加密。

依赖:UniApp 无内置 crypto,App 端用 plus.crypto(需条件编译)。

示例(简单 Base64 + 自定义密钥,H5/小程序通用):

javascript 复制代码
// utils/encrypt.js
const KEY = 'MySecretKey12345';  // 生产环境用随机密钥

function encrypt(data) {
  const str = typeof data === 'object' ? JSON.stringify(data) : data;
  let result = '';
  for (let i = 0; i < str.length; i++) {
    result += String.fromCharCode(str.charCodeAt(i) ^ KEY.charCodeAt(i % KEY.length));
  }
  return btoa(result);  // Base64 编码
}

function decrypt(encrypted) {
  try {
    const decoded = atob(encrypted);
    let result = '';
    for (let i = 0; i < decoded.length; i++) {
      result += String.fromCharCode(decoded.charCodeAt(i) ^ KEY.charCodeAt(i % KEY.length));
    }
    return JSON.parse(result);  // 假设对象
  } catch (e) {
    return null;
  }
}

// 使用
uni.setStorageSync('encrypted_token', encrypt('abc123'));
const token = decrypt(uni.getStorageSync('encrypted_token'));

注意:H5 用 CryptoJS 库(npm 引入),App 用原生。对于金融类 App,这层保护至关重要,能防范简单逆向工程。

3.5 批量操作与事务模拟

原理:无原生事务,用 Promise.all 模拟批量。

示例:

javascript 复制代码
async batchSet(items) {
  const promises = items.map(({ key, data }) =>
    new Promise((resolve, reject) => {
      uni.setStorage({
        key,
        data,
        success: resolve,
        fail: reject
      });
    })
  );
  try {
    await Promise.all(promises);
    console.log('批量存储成功');
  } catch (e) {
    console.error('批量失败,回滚');
    // 模拟回滚:清空相关键
    items.forEach(({ key }) => uni.removeStorageSync(key));
  }
}

// 调用
this.batchSet([
  { key: 'config1', data: { theme: 'dark' } },
  { key: 'config2', data: { lang: 'zh' } }
]);

规则:失败时回滚,确保一致性。适用于配置批量更新,在初始化多模块时很实用。

四、实际应用场景

本节通过 4 个典型场景,展示缓存的实战价值。每场景包含需求、实现和优化。

4.1 用户登录状态管理

需求:登录后保存 Token 和用户信息,退出时清除;重启 App 自动验证。

实现

  • 登录页(login.vue):
javascript 复制代码
login() {
  // 模拟 API
  const user = { id: 1, name: '李四', token: 'def456' };
  uni.setStorageSync('user_token', user.token);
  uni.setStorageSync('user_info', JSON.stringify(user));
  uni.switchTab({ url: '/pages/home/home' });
}
  • Home 页(home.vue):
javascript 复制代码
onLoad() {
  const token = uni.getStorageSync('user_token');
  if (token) {
    const userStr = uni.getStorageSync('user_info');
    this.user = userStr ? JSON.parse(userStr) : null;
  } else {
    uni.reLaunch({ url: '/pages/login/login' });
  }
},
methods: {
  logout() {
    uni.removeStorageSync('user_token');
    uni.removeStorageSync('user_info');
    uni.reLaunch({ url: '/pages/login/login' });
  }
}

优化:集成过期(3.1),每 7 天重登。

在实际项目中,可添加 JWT 解析验证 Token 有效性:

javascript 复制代码
// 验证 Token
function isTokenValid(token) {
  try {
    const payload = JSON.parse(atob(token.split('.')[1]));
    return Date.now() < payload.exp * 1000;
  } catch (e) {
    return false;
  }
}

这确保安全,防止过期 Token 误用。在社交 App 中,这种机制让用户体验更流畅。

4.2 配置信息持久化

需求:保存主题色、语言等设置,重启生效。

实现

  • 设置页(setting.vue):
javascript 复制代码
changeTheme(color) {
  uni.setStorageSync('app_theme', color);
  // 动态更新全局样式(需 CSS 变量)
  const dom = document.documentElement;
  dom.style.setProperty('--theme-color', color);
}
onLoad() {
  const savedTheme = uni.getStorageSync('app_theme') || '#007AFF';
  // 应用主题
}

优化:用 getStorageInfo 监控,超 1MB 提示清理。结合 Vuex(3.2),实现响应式切换。

扩展:多语言支持:

javascript 复制代码
// 存储语言包
uni.setStorageSync('lang_pack', { zh: { hello: '你好' }, en: { hello: 'Hello' } });
const lang = uni.getStorageSync('current_lang') || 'zh';
this.messages = uni.getStorageSync('lang_pack')[lang];

这在国际化 App 中实用,减少 bundle 大小。用户切换语言时,立即生效,无需重启。

4.3 离线数据缓存

需求:缓存 API 返回的文章列表,支持无网浏览。

实现(使用 3.1 过期):

javascript 复制代码
// 获取列表
async fetchArticles() {
  const cached = getWithExpire('articles');
  if (cached) {
    this.articles = cached;
    return;
  }
  
  try {
    const res = await uni.request({ url: '/api/articles' });
    setWithExpire('articles', res.data, 24 * 60 * 60 * 1000);  // 24小时
    this.articles = res.data;
  } catch (e) {
    console.error('网络错误,使用缓存');
    this.articles = cached || [];
  }
}

优化:分页缓存,如 'articles_page_1'。添加网络状态检测:

javascript 复制代码
uni.getNetworkType({
  success: (res) => {
    if (res.networkType === 'none') {
      // 仅用缓存
    }
  }
});

这提升了鲁棒性,在弱网环境闪光。新闻类 App 中,用户地铁上也能阅读缓存内容。

4.4 列表分页缓存

需求:电商商品列表,分页加载,缓存每页数据。

实现

javascript 复制代码
loadPage(page = 1) {
  const key = `goods_page_${page}`;
  const cached = uni.getStorageSync(key);
  if (cached) {
    this.goods = [...this.goods, ...cached];
    return;
  }
  
  uni.request({
    url: `/api/goods?page=${page}`,
    success: (res) => {
      uni.setStorageSync(key, res.data);
      this.goods = [...this.goods, ...res.data];
    }
  });
}

优化:预加载下一页,移除旧页(如 >10 页清空)。结合 getStorageInfo,避免总大小超限。

扩展讨论:在高并发场景,可用 IndexedDB(H5 专用,条件编译)补充大列表缓存:

vue 复制代码
<!-- #ifdef H5 -->
<script>
import { openDB } from 'idb';  // npm idb
const db = await openDB('goods_db', 1, {
  upgrade(db) {
    db.createObjectStore('pages');
  }
});
await db.put('pages', data, `page_${page}`);
</script>
<!-- #endif -->

这在 Web 端处理海量数据时高效,结合缓存层,能实现混合存储策略。

五、性能优化与最佳实践

5.1 同步 vs 异步选择

  • 异步优先:95% 场景用回调/Promise,避免 UI 阻塞。示例:onLoad 中异步 get。
  • 同步场景:启动时快速恢复,或简单工具函数。
  • 最佳实践:封装 Promise 化异步:
javascript 复制代码
function setStoragePromise(key, data) {
  return new Promise((resolve, reject) => {
    uni.setStorage({
      key, data,
      success: resolve,
      fail: reject
    });
  });
}
// 使用 await setStoragePromise('key', data);

在我的项目中,统一用 Promise,能让 async/await 代码更优雅。

5.2 存储大小管理

  • 监控:定期调用 getStorageInfo,若 currentSize > 80% limitSize,清理旧数据。
  • 压缩:大对象用 lz-string 库压缩(npm 引入)。
  • 实践:设置页添加"清理缓存"按钮:
javascript 复制代码
clearOld() {
  const res = uni.getStorageInfoSync();
  if (res.currentSize > res.limitSize * 0.8) {
    // 移除 7 天前数据(结合 3.1)
    res.keys.forEach(key => {
      if (getWithExpire(key) === null) uni.removeStorageSync(key);
    });
  }
}

定期清理能保持 App 轻量,尤其在低端设备上。

5.3 错误处理与调试

  • 统一日志:用 console.error + uni.reportEvent 上报。
  • 调试工具:HBuilderX 控制台查看 Storage,Chrome DevTools 检查 H5 localStorage。
  • 实践:添加 try-catch 包装所有操作,fail 回调 toast 提示。遇到序列化错误时,fallback 到字符串存储。

5.4 跨平台兼容

  • 条件编译:#ifdef APP 用 plus.storage 扩展。
  • 测试:多端运行,关注小程序审核(如支付宝 10MB 限)。
  • 实践:manifest.json 中配置 storage 权限。在 CI/CD 中集成多端测试脚本。

5.5 清理策略

  • 自动:应用退出时 clear(可选)。
  • 手动:用户设置页一键清。
  • 智能:基于使用频率,LRU(最近最少用)算法移除(自定义 Map 实现)。

示例 LRU:

javascript 复制代码
class LRUCache {
  constructor(maxSize) {
    this.maxSize = maxSize;
    this.cache = new Map();
  }
  set(key, value) {
    if (this.cache.has(key)) this.cache.delete(key);
    this.cache.set(key, value);
    if (this.cache.size > this.maxSize) {
      const firstKey = this.cache.keys().next().value;
      this.cache.delete(firstKey);
    }
  }
  get(key) {
    if (this.cache.has(key)) {
      const value = this.cache.get(key);
      this.cache.delete(key);
      this.cache.set(key, value);
      return value;
    }
    return null;
  }
}

用它包装 Storage,能智能管理热数据。

六、常见问题与解决方案

6.1 常见错误

  • 序列化失败 :data 含不可序列化类型。
    :预检查 JSON.stringify(data) 不抛错。
  • Key 冲突 :用系统前缀。
    :命名规范,如 'app_user_token'。
  • 读取 undefined :key 不存在。
    :默认值 || {}

6.2 平台特定问题

  • H5 缓存丢失 :浏览器隐私模式。
    :fallback 到 sessionStorage。
  • 小程序超限 :微信 10MB。
    :分 key 存储,定期 getStorageInfo 检查。
  • App 无限制滥用 :占用设备空间。
    :设置软上限 50MB,自行清理。

6.3 调试技巧

  • 打印 keys:循环 getStorageSync(key) 查看内容。
  • 模拟清理:clearStorageSync() + 重载。
  • 工具:UniApp 插件"Storage Viewer"。在开发时,添加一个调试模式,暴露所有 keys 到控制台。

七、扩展与进阶

7.1 与其他存储结合

  • SQLite (App 端):复杂数据用 uni.requireNativePlugin('sqlite')。
    示例:用户订单表,缓存仅存 ID 列表。
  • IndexedDB (H5):大文件缓存。
    实践:图片缩略图存 IndexedDB,详情存 Storage。混合使用能平衡性能和容量。

7.2 云端同步

  • 原理:本地变更时上传云(uniCloud),拉取时合并。
  • 示例:登录后 syncCacheToCloud(),用 diff 算法避免覆盖。
javascript 复制代码
async syncCache() {
  const localKeys = uni.getStorageInfoSync().keys;
  const cloudData = await uniCloud.callFunction({ name: 'getCache' });
  localKeys.forEach(key => {
    if (!cloudData.has(key)) {
      uniCloud.callFunction({ name: 'uploadCache', data: { key, value: uni.getStorageSync(key) } });
    }
  });
}

这在多设备同步场景中强大,如笔记 App。

7.3 自定义缓存模块

  • 基于 Redux-like:状态 + reducer + storage middleware。
  • 进阶:支持 RxJS 响应式缓存更新。示例:订阅缓存变化,自动 UI 刷新。
javascript 复制代码
// 用 RxJS
import { fromEvent } from 'rxjs';
const storageEvent = fromEvent(window, 'storage');
storageEvent.subscribe(event => {
  if (event.key === 'my_key') {
    // 更新状态
  }
});

这让缓存成为响应式数据源。

相关推荐
开发者小天3 小时前
uniapp中对接开发激励广告视频
uni-app
情深不寿3173 小时前
MySQL————mysql connect
1024程序员节
AI浩3 小时前
MFFCI-YOLOv8:一种基于多尺度特征融合与上下文信息的轻量级遥感目标检测网络
1024程序员节
mit6.8243 小时前
[OP-Agent] 可扩展架构 | 插件管理器plugins.go
go·1024程序员节
cai_huaer4 小时前
BugKu Web渗透之 文件包含2
web安全·1024程序员节
蓝天居士4 小时前
PY32F040单片机介绍(1)
单片机·国产mcu·1024程序员节
ʚ希希ɞ ྀ4 小时前
初学JVM---什么是JVM
1024程序员节
2401_888859714 小时前
STM32_bug总结-运行函数在SystemInit之后就卡死
1024程序员节
G佳伟4 小时前
PHP拆分重组pdf,php拆分pdf指定页数,并合并成新pdf
1024程序员节