前端 IndexDB 使用指南

目录

IndexedDB 一句话理解

📊 对比 localStorage

🎯 使用场景(什么时候用?)

💡 使用示例

⚠️ 注意事项

IDB 完整使用指南

1. 安装与基础操作

安装

四个核心方法

2. 完整工具类封装

3. React 组件中使用

4. 关键概念说明

📌 必知要点

5. 官方资源

6. 故障排除


IndexedDB 一句话理解

浏览器里的大容量本地数据库,比 localStorage 能存更多、更复杂的数据。

📊 对比 localStorage

特性localStorageIndexedDB
容量5MB至少250MB,甚至GB级
数据类型字符串任何JS对象、文件、二进制
查询方式键值对键值、索引、范围查询
速度同步(阻塞)异步(不阻塞页面)

🎯 使用场景(什么时候用?)

用 localStorage:

  • 存 token、用户设置等小数据
  • 简单键值对,数据量 < 5MB

用 IndexedDB:

  • 离线应用的全部数据
  • 用户生成的内容(图片、笔记)
  • 应用缓存(大量API数据)
  • 编辑器草稿自动保存

💡 使用示例

// 存文件/图片 await db.put('files', { id: 'photo1', name: '头像.jpg', data: fileBlob, // 二进制文件 size: '2MB' }); // 复杂查询(localStorage做不到) const expensiveProducts = await db .getAllFromIndex('products', 'price', IDBKeyRange.lowerBound(1000));

⚠️ 注意事项

不要用 IndexedDB 存:

  • 密码等敏感信息(不安全)
  • 实时同步数据(用 WebSocket)
  • 服务器端数据(用API)

应该用 IndexedDB 存:

  • 离线可用的用户数据
  • 大型应用的本地缓存
  • 用户上传的文件本地副本

一句话总结:需要存大量复杂数据且支持离线访问时,用 IndexedDB。

IDB 完整使用指南

1. 安装与基础操作

安装

yarn add idb

四个核心方法

import { openDB } from 'idb'; // 1. 打开/创建数据库(首次运行时会自动创建) const db = await openDB('MyAppDB', 1, { // 参数:数据库名,版本号 upgrade(db) { // 只在版本更新或初次创建时执行 // 创建对象仓库(相当于数据库表) db.createObjectStore('tasks', { keyPath: 'id' // 指定主键为 id 字段 }); } }); // 2. 添加或更新数据 await db.put('tasks', { id: 1, // 必须有 id 字段,作为主键 title: '学习 IDB', completed: false }); // 3. 查询所有数据 const allTasks = await db.getAll('tasks'); // 4. 根据 id 查询单条 const task = await db.get('tasks', 1); // 5. 根据 id 删除 await db.delete('tasks', 1);

2. 完整工具类封装

import { openDB } from 'idb'; class TaskDB { constructor() { this.dbName = 'TaskDatabase'; this.storeName = 'tasks'; this.version = 1; } // 初始化数据库连接 async connect() { return openDB(this.dbName, this.version, { upgrade(db) { // 如果 tasks 表不存在就创建 if (!db.objectStoreNames.contains('tasks')) { db.createObjectStore('tasks', { keyPath: 'id' // 主键字段 }); } } }); } // 增/改:保存任务 async saveTask(task) { const db = await this.connect(); // put 方法:id 存在则更新,不存在则新增 return db.put(this.storeName, task); } // 删:删除任务 async deleteTask(id) { const db = await this.connect(); return db.delete(this.storeName, id); } // 查:获取所有任务 async getAllTasks() { const db = await this.connect(); return db.getAll(this.storeName); } // 查:根据 id 获取单个任务 async getTask(id) { const db = await this.connect(); return db.get(this.storeName, id); } } export default new TaskDB(); // 导出单例实例

3. React 组件中使用

import React, { useState, useEffect } from 'react'; import taskDB from './taskDB'; // 导入上面封装的数据库工具 function TaskManager() { const [tasks, setTasks] = useState([]); const [newTaskTitle, setNewTaskTitle] = useState(''); // 组件加载时从数据库读取所有任务 useEffect(() => { loadTasks(); }, []); // 从数据库加载任务 const loadTasks = async () => { const savedTasks = await taskDB.getAllTasks(); setTasks(savedTasks || []); // 处理空数据情况 }; // 添加新任务 const handleAddTask = async () => { if (!newTaskTitle.trim()) return; const newTask = { id: Date.now(), // 使用时间戳作为唯一 ID title: newTaskTitle, completed: false, createdAt: new Date().toISOString() }; // 1. 保存到数据库 await taskDB.saveTask(newTask); // 2. 更新界面状态 setTasks([...tasks, newTask]); setNewTaskTitle(''); }; // 切换任务完成状态 const handleToggleTask = async (task) => { const updatedTask = { ...task, completed: !task.completed }; // 1. 更新数据库 await taskDB.saveTask(updatedTask); // 2. 更新界面状态 setTasks(tasks.map(t => t.id === task.id ? updatedTask : t )); }; // 删除任务 const handleDeleteTask = async (taskId) => { // 1. 从数据库删除 await taskDB.deleteTask(taskId); // 2. 从界面状态删除 setTasks(tasks.filter(task => task.id !== taskId)); }; return ( <div className="task-manager"> <h1>任务管理器</h1> {/* 添加任务表单 */} <div className="add-task"> <input type="text" value={newTaskTitle} onChange={(e) => setNewTaskTitle(e.target.value)} placeholder="输入新任务..." /> <button onClick={handleAddTask}>添加</button> </div> {/* 任务列表 */} <ul className="task-list"> {tasks.map(task => ( <li key={task.id} className={task.completed ? 'completed' : ''}> <input type="checkbox" checked={task.completed} onChange={() => handleToggleTask(task)} /> <span>{task.title}</span> <button onClick={() => handleDeleteTask(task.id)} className="delete-btn" > 删除 </button> </li> ))} </ul> {/* 统计信息 */} <div className="stats"> 总计: {tasks.length} 个任务 | 已完成: {tasks.filter(t => t.completed).length} | 未完成: {tasks.filter(t => !t.completed).length} </div> </div> ); } export default TaskManager;

4. 关键概念说明

📌 必知要点

  1. keyPath: 'id':指定数据的主键字段,每条数据必须有唯一的 id
  2. put() vs add()
    • put():id 存在则更新,不存在则新增
    • add():只能新增,id 重复会报错
  3. 版本控制:修改数据库结构时需增加版本号
// 版本升级示例 openDB('MyDB', 2, { // 版本从 1 升到 2 upgrade(db, oldVersion) { if (oldVersion < 1) { // 初始创建 db.createObjectStore('tasks', { keyPath: 'id' }); } if (oldVersion < 2) { // 新增索引(可按标题搜索) const store = db.transaction.objectStore('tasks'); store.createIndex('title', 'title'); } } });

5. 官方资源

6. 故障排除

// 1. 确保所有操作都是异步的 try { const db = await openDB(...); await db.put(...); } catch (error) { console.error('数据库错误:', error); } // 2. 检查浏览器兼容性 if (!window.indexedDB) { alert('您的浏览器不支持 IndexedDB'); } // 3. 清除缓存(开发时有用) indexedDB.deleteDatabase('MyAppDB');

💡 一句话总结openDB 打开数据库,put 保存数据,get 查询数据,delete 删除数据,所有操作都要加 await

Read more

对比测试:Fun-ASR与Whisper语音识别效果与速度差异

对比测试:Fun-ASR与Whisper语音识别效果与速度差异 在企业办公场景中,每天都有成百上千小时的会议录音、客服通话和培训音频亟待处理。如何高效地将这些声音“翻译”成可搜索、可分析的文字?这不仅是效率问题,更是数据资产化的核心环节。过去几年,语音识别技术突飞猛进,尤其是OpenAI推出的Whisper系列模型,一度被视为行业标杆。然而,在真实中文语境下——口音多样、术语密集、环境嘈杂——通用型模型的表现往往不尽如人意。 正是在这种背景下,钉钉联合通义实验室推出的Fun-ASR逐渐进入开发者视野。它不追求“支持99种语言”的广度,而是聚焦于一件事:把中文说得更准、转得更快、用得更稳。更重要的是,它不是一段代码或一个API,而是一整套可以本地运行、开箱即用的语音识别系统,自带Web界面、热词增强、批量处理和历史管理功能。对于需要私有化部署、保障数据安全的企业来说,这种设计思路显然更具现实意义。 那么,当Fun-ASR真正面对Whisper时,差距究竟在哪里?是精度更高,还是速度快到质变?又或者只是“本地可用”这一点就足以决定胜负? 我们不妨从一次真实的批量转写任务说起。 假

Llama-3.2-3B部署实录:Ollama本地大模型从下载到生成仅需90秒

Llama-3.2-3B部署实录:Ollama本地大模型从下载到生成仅需90秒 想体验最新的大语言模型,但又担心复杂的部署流程和漫长的等待时间?今天,我要分享一个极其简单的方案:使用Ollama在本地部署Meta最新发布的Llama-3.2-3B模型。整个过程从下载模型到生成第一段文字,最快只需要90秒,而且完全免费,不需要任何复杂的配置。 Llama-3.2-3B是Meta推出的轻量级多语言大模型,虽然只有30亿参数,但在很多任务上的表现已经相当出色。更重要的是,它非常“亲民”,对普通电脑配置要求不高,通过Ollama这个工具,你可以像安装一个普通软件一样把它装到自己的电脑上,随时随地调用。 这篇文章,我将带你走一遍完整的部署流程,从零开始,手把手教你如何用最简单的方法,在自己的电脑上跑起这个强大的AI助手。 1. 准备工作:认识我们的工具和模型 在开始动手之前,我们先花一分钟了解一下今天要用到的两个核心:Ollama和Llama-3.2-3B模型。了解它们是什么,能帮你更好地理解后面的每一步操作。 1.1 Ollama:你的本地大模型管家 你可以把Ollama想象成

llama.cpp终极内存优化指南:让大模型推理性能飙升200%

llama.cpp终极内存优化指南:让大模型推理性能飙升200% 【免费下载链接】llama.cppPort of Facebook's LLaMA model in C/C++ 项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp 在资源受限环境下运行大型语言模型时,内存管理往往成为制约性能的关键瓶颈。llama.cpp作为C/C++实现的LLaMA模型移植项目,通过创新的内存池架构从根本上解决了这一挑战。本文将深入解析其内存优化策略,为技术决策者和架构师提供完整的性能调优方案。 从内存碎片化到高效推理的技术演进 传统动态内存分配在大模型推理场景下面临严峻挑战:频繁的malloc/free操作导致内存碎片化严重,KV缓存的持续分配与释放直接拖累推理速度。llama.cpp采用预分配与复用机制的革命性思路,在模型启动时根据参数分配连续内存块,通过状态标记实现内存块的循环利用。 图:矩阵乘法中行优先与列优先存储方式对内存访问模式的影响 架构设计哲学:分层抽象与统一接口 llama.cpp的内存管理体系建立在三个关键

如何部署本地 stable diffusion 本地使用大模型Z Image Turbo

🛠️ 部署 Stable Diffusion 详细步骤(以 Automatic1111 WebUI 为例) 1. 准备工作(系统和硬件要求) * 操作系统: Windows 10/11, macOS (Apple Silicon 芯片), 或 Linux。NVIDIA: 推荐使用 NVIDIA 显卡(RTX 系列为佳),显存 (VRAM) 最好在 8GB 或以上。这是 Windows 上运行 SD 性能最好的选择。 * 显卡 (GPU): * AMD: 也可以,但设置可能更复杂,且性能通常不如 NVIDIA。 * Apple Silicon (M系列芯片): 在 macOS 上性能优秀,