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

Vue 3 中封装并使用 IndexedDB 的完整教程(含泛型、模块化、通用 CRUD)

🧩Vue 3 中封装并使用 IndexedDB 的完整教程(含泛型、模块化、通用 CRUD)

📌 适用于需要本地缓存、离线存储、聊天记录、本地草稿等场景

👍 记得收藏 + 点赞 + 关注,让这篇教程成为你项目中本地存储的标准方案!


一、🧠 IndexedDB 是什么?

IndexedDB 是浏览器中内置的 NoSQL 数据库,可以在客户端存储大量结构化数据。相比 localStorage,它更强大,支持对象存储、事务管理、索引查询,容量也更大(百 MB 级别)。


二、📦 安装封装依赖(使用 idb)

idb 是 Google 开发的 IndexedDB Promise 封装库,语法清晰,非常适合 Vue 项目。

npm install idb

三、🧱 创建通用封装模块(支持泛型)

📁 路径建议:src/utils/indexedDb.ts

// utils/indexedDb.ts
import { openDB, type IDBPDatabase } from 'idb'// 可扩展的数据表名(store)
type StoreName = 'users' | 'messages'// 每个 store 的配置
export interface DBStoreConfig<T> {name: StoreNamekeyPath: stringdata?: T[] // 可选:初始化数据
}let db: IDBPDatabase | null = null// 初始化数据库
export async function initDB(stores: DBStoreConfig<any>[]) {db = await openDB('MyAppDB', 1, {upgrade(database) {stores.forEach(store => {if (!database.objectStoreNames.contains(store.name)) {const objectStore = database.createObjectStore(store.name, {keyPath: store.keyPath,})if (store.data) {store.data.forEach(item => objectStore.add(item))}}})},})return db
}// 获取某个 store
function getStore<T>(storeName: StoreName, mode: IDBTransactionMode = 'readonly') {if (!db) throw new Error('数据库尚未初始化')return db.transaction(storeName, mode).objectStore(storeName)
}// 通用 CRUD API
export async function addItem<T>(store: StoreName, item: T) {return await getStore<T>(store, 'readwrite').add(item)
}export async function putItem<T>(store: StoreName, item: T) {return await getStore<T>(store, 'readwrite').put(item)
}export async function deleteItem(store: StoreName, key: IDBValidKey) {return await getStore(store, 'readwrite').delete(key)
}export async function getItem<T>(store: StoreName, key: IDBValidKey) {return await getStore<T>(store).get(key)
}export async function getAll<T>(store: StoreName): Promise<T[]> {return await getStore<T>(store).getAll()
}export async function clearStore(store: StoreName) {return await getStore(store, 'readwrite').clear()
}

四、🚀 在 Vue 项目中初始化数据库

📄 main.ts 中初始化:

import { createApp } from 'vue'
import App from './App.vue'
import { initDB } from './utils/indexedDb'const app = createApp(App)await initDB([{ name: 'users', keyPath: 'id' },{ name: 'messages', keyPath: 'id' },
])app.mount('#app')

五、🧪 使用示例组件:用户管理

📄 components/UserList.vue

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { getAll, addItem, deleteItem } from '@/utils/indexedDb'interface User {id: numbername: string
}const users = ref<User[]>([])const loadUsers = async () => {users.value = await getAll<User>('users')
}const addUser = async () => {await addItem<User>('users', {id: Date.now(),name: '新用户'})await loadUsers()
}const deleteUser = async (id: number) => {await deleteItem('users', id)await loadUsers()
}onMounted(() => {loadUsers()
})
</script><template><div class="user-list"><h3>📋 用户列表</h3><ul><li v-for="user in users" :key="user.id">{{ user.name }}<button @click="deleteUser(user.id)">删除</button></li></ul><button @click="addUser">➕ 添加用户</button></div>
</template>

六、✅ 常见用法总结

功能方法
添加记录addItem<T>(store, item)
更新记录putItem<T>(store, item)
获取单条记录getItem<T>(store, key)
获取所有记录getAll<T>(store)
删除记录deleteItem(store, key)
清空数据表clearStore(store)

七、📁 DevTools 调试技巧

打开浏览器 DevTools → Application → IndexedDB

  • 查看数据库名(MyAppDB)
  • 点击 store(如 users)查看数据内容
  • 可以直接修改/删除记录进行调试

八、💡 进阶建议(可选扩展)

  • ✅ 支持索引搜索(使用 store.createIndex()
  • ✅ 支持 blob(二进制存储:图片、文件)
  • ✅ 封装成 Vue 插件,全局注入数据库服务
  • ✅ 添加导入/导出功能(用于备份与恢复)

📌 总结

IndexedDB 是 Vue 项目中本地离线缓存、数据草稿、聊天存档等功能的理想选择。通过本教程你可以:

✅ 封装可复用模块
✅ 类型安全 + 泛型支持
✅ 在组件中轻松调用 CRUD
✅ 配合 DevTools 调试、浏览本地数据


🧭 下一步建议

如果你希望我继续扩展以下功能,请评论告诉我:

  • 🖼 IndexedDB 本地图片存储封装
  • 💬 聊天消息分页存储
  • 🧩 整库导出/导入(导出为 JSON)

📌 如果这份教程对你有帮助,欢迎收藏 + 点赞 + 关注,让我们一起把 Vue 项目写得更优雅!

http://www.lryc.cn/news/593466.html

相关文章:

  • Vue Swiper组件
  • 93.数字信号处理相关的一些问题
  • 单元测试学习+AI辅助单测
  • 【ArcGIS技巧】最近分享的GIS插件总结与优化
  • Spring MVC源码分析 DispatcherServlet#getHandlerAdapter方法
  • LVS四种工作模式深度解析
  • Go 语言核心机制深度剖析:指针、defer、多态与空接口实战指南
  • 使用 go-redis-entraid 实现 Entra ID 无密钥认证
  • Go-Redis × RediSearch 全流程实践
  • leetcode_121 买卖股票的最佳时期
  • 力扣经典算法篇-26-长度最小的子数组(暴力求解法,左右指针法)
  • 【Java】【力扣】48.旋转图像
  • FPGA自学——整体设计思路
  • Redis数据库基础与持久化部署
  • 使用CCS6.2为C2000(DSP28335)生成.bin文件和.hex文件
  • 【LeetCode 热题 100】437. 路径总和 III——(解法一)递归递归!
  • CCF编程能力等级认证GESP—C++7级—20250628
  • STM32_Hal库学习ADC
  • IntelliJ IDEA中Mybatis的xml文件报错解决
  • SSM框架——注入类型
  • aws(学习笔记第四十九课) ECS集中练习(1)
  • Streamlit 官翻 5 - 部署、社区云 Deploy
  • Python绘制数据(三)
  • Matplotlib 30分钟精通
  • 人该怎样活着呢?55
  • Windows11下编译好的opencv4.8-mingw,可下载后直接用
  • Apache Kafka 学习笔记
  • 详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
  • Python高级数据类型:字典(Dictionary)
  • Datawhale 7月学习