存储管理
Store 模块 提供了对浏览器全链路存储机制的统一封装。
从页面级的临时内存,到持久化的 LocalStorage/Cookie,再到海量数据的 IndexedDB,您都可以通过统一的 API 风格进行管理。
引入方式
import { tStore, tDBM } from "@techui/utils";内存临时存储
tStore 本身即是一个轻量级的全局状态缓存池。 它基于 Map 实现,数据仅在当前页面生命周期内有效(刷新即逝)。相比 Vuex/Pinia,它更轻量,适合在非 Vue 组件环境(如纯 JS 工具函数)中共享数据。
核心 API
- s(key, val): Set。写入数据。
- g(key, del?): Get。读取数据。
del为true时读取后立即删除(阅后即焚)。 - d(key): Delete。删除数据。
场景一:跨组件/模块传参
在不引入复杂状态管理库的情况下,在两个独立的 JS 模块间共享配置。
// moduleA.js
tStore.s('appConfig', {
apiHost: 'https://api.techui.net',
timeout: 5000
});
// moduleB.js
const config = tStore.g('appConfig');
console.log(config.apiHost); // "https://api.techui.net"场景二:一次性消息 (Flash Message)
常用于页面跳转后的成功提示,读取一次后自动销毁,防止重复显示。
// 在登录页
tStore.s('loginSuccessMsg', '欢迎回来,Ayin!');
// 在首页初始化时
const msg = tStore.g('loginSuccessMsg', true); // true 开启阅后即焚
if (msg) {
alert(msg); // 显示欢迎
}
// 再次读取
console.log(tStore.g('loginSuccessMsg')); // undefinedCookie 管理
tStore.cookie 提供了对 document.cookie 的简便封装,解决了原生 Cookie 操作晦涩难用的问题。
核心 API
- s(name, val, expire): 写入。
expire为过期时间(单位:秒)。 - g(name): 读取。会自动进行
unescape解码。 - d(name): 删除。
场景一:设置短期 Token (1小时)
// 登录成功,保存 Token,有效期 3600 秒
tStore.cookie.s('access_token', 'eyJhbGciOiJIUz...', 3600);场景二:设置长期偏好 (7天)
// 保存用户广告偏好,7天有效
const sevenDays = 60 * 60 * 24 * 7;
tStore.cookie.s('ad_preference', 'low', sevenDays);场景三:退出登录 (删除 Cookie)
// 退出登录时清除
tStore.cookie.d('access_token');
// 验证是否删除
console.log(tStore.cookie.g('access_token')); // "" (空字符串)本地存储
tStore.local 是对 localStorage 的增强封装。 它最大的特点是自动序列化:您再也不用手动写 JSON.stringify 和 JSON.parse 了。
核心 API
- s(key, val): 写入。支持对象、数组、字符串等任意类型。
- g(key): 读取。内置 JSON 解析容错。
- d(key): 删除。
场景一:持久化用户设置
即使用户关闭浏览器,下次打开依然存在的配置。
// 写入对象
const settings = {
theme: 'dark',
fontSize: 14,
sidebarCollapsed: true
};
tStore.local.s('user_settings', settings);场景二:读取并使用
const savedSettings = tStore.local.g('user_settings');
if (savedSettings && savedSettings.theme === 'dark') {
enableDarkMode();
}场景三:容错处理
假设某个 Key 被外部脚本被错误地写入了非 JSON 字符串(如 "undefined"),tStore 会优雅降级返回原字符串,而不会报错导致页面白屏。
// 模拟脏数据
localStorage.setItem('bad_data', '{ key: "invalid json" }'); // 缺少引号的非法JSON
const val = tStore.local.g('bad_data');
console.log(val); // 原样返回字符串 '{ key: "invalid json" }',不会抛出 SyntaxError会话存储
tStore.session 的 API 与 local 完全一致,但数据仅在当前标签页关闭前有效。
场景一:表单临时草稿
用户填写长表单时不小心刷新了页面,数据不应丢失;但关闭标签页后应清除,避免污染下次操作。
// 监听输入框变化
input.addEventListener('input', (e) => {
tStore.session.s('form_draft_title', e.target.value);
});
// 页面加载时恢复
const draft = tStore.session.g('form_draft_title');
if (draft) input.value = draft;场景二:页面访问面包屑
记录用户在当前会话中的访问路径。
const history = tStore.session.g('breadcrumbs') || [];
history.push({ name: 'UserDetail', id: 101 });
tStore.session.s('breadcrumbs', history);浏览器数据库管理
tDBM (TechUI Database Manager) 是本模块中最强大的工具。 它将复杂的 IndexedDB 操作封装为简单的 Promise 调用,适合存储大量结构化数据(如日志、离线文档、大屏数据缓存)。
初始化结构 (Init)
在使用前,必须先定义数据库表结构(Schema)。
// 定义表结构
const stores = [
{
name: 'logs', // 表名
keyPath: 'id', // 主键
autoIncrement: true, // 自增
indexes: [ // 索引
{ name: 'level', keyPath: 'lvl' },
{ name: 'date', keyPath: 'timestamp' }
]
},
{
name: 'cache_files',
keyPath: 'url' // 使用 URL 作为主键
}
];
// 初始化数据库 'MyAppDB',版本号 1
await tDBM.init('MyAppDB', 1, stores);场景一:批量写入 (高性能)
比循环调用 add 快得多,适合初始化导入数据。
const logs = [
{ lvl: 'info', msg: 'App started', timestamp: Date.now() },
{ lvl: 'error', msg: 'Network error', timestamp: Date.now() + 100 },
// ... 更多数据
];
// 批量插入
await tDBM.add('logs', logs);
console.log('日志写入完成');场景二:更新或插入 (Upsert)
用于同步服务器数据,如果 ID 存在则更新,不存在则新增。
const userProfile = {
url: '/api/user/1',
data: { name: 'Ayin', role: 'admin' },
cachedAt: Date.now()
};
// 使用 put 方法
await tDBM.put('cache_files', userProfile);场景三:按索引查询
不通过 ID,而是通过业务字段查询。
// 查询所有 'error' 级别的日志
const errors = await tDBM.getByIndex('logs', 'level', 'error');
console.log(`共发现 ${errors.length} 条错误日志`);场景四:大数据量游标遍历
当表中存有几万条数据时,直接 getAll 会导致内存溢出。使用 iterate 游标逐条处理。
// 遍历所有日志
await tDBM.iterate('logs', (cursor, value) => {
if (value.timestamp < Date.now() - 86400000) {
// 删除 1 天前的过期日志
cursor.delete();
console.log('已删除过期日志:', value.id);
}
});场景五:数据库信息查看与维护
// 检查数据库是否已连接
if (tDBM.isInited()) {
const info = tDBM.info();
console.log(`当前数据库版本: ${info.version}, 包含表: ${info.tables.join(',')}`);
}
// 彻底删除数据库 (需先关闭连接)
tDBM.close();
await tDBM.deleteDatabase('MyAppDB');