当前位置: 首页 > 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.dtcms.com/a/287404.html

相关文章:

  • 【C# in .NET】20. 探秘静态类:抽象与密封的结合体
  • Spring AI 1.0版本 + 千问大模型之 文本记忆对话
  • LeetCode中等题--167.两数之和II-输入有序数组
  • MySQL基础教程
  • XSS漏洞----基于Dom的xss
  • 力扣24:两两交换链表中的节点
  • SQLALchemy
  • 单元测试学习+AI辅助单测
  • 计算机网络:(十一)多协议标记交换 MPLS
  • GaussDB union 的用法
  • Java NIO Selector高并发场景下CPU占用飙升问题排查与解决方案
  • NIO零拷贝
  • MySQL的union、union all导致排序失效
  • 低输入电源5.5V/2A同步降压转换器具有多种模式选择
  • roslaunch 文件的核心语法和使用技巧
  • (LeetCode 每日一题) 1233. 删除子文件夹 (排序)
  • TCP/UDP协议深度解析(四):TCP的粘包问题以及异常情况处理
  • 7.19 换根dp | vpp |滑窗
  • 医养照护与管理实训基地建设:创新模式与突破路径
  • 扭蛋机系统开发:打造多元化娱乐生态的新引擎
  • 响应式单位rpx及搭配使用UI产品工具
  • Ambiguity-Resolved Waveform Design for Cell-free OFDM-Based ISAC Systems
  • 【MySQL笔记】视图
  • 力扣 hot100 Day49
  • day25 力扣90.子集II 力扣46.全排列 力扣47.全排列 II
  • 二、环境搭建之CentOS安装Docker
  • GitHub:只支持 Git 作为唯一的版本库格式进行托管
  • 二分查找-69.x的平方根-力扣(LeetCode)
  • 安装单机版本Redis
  • 电商商品综合排序:从需求分析到实时计算的全方位指南