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 项目写得更优雅!