IndexedDB 本地数据库的使用

本次模拟的是 存储数组类型

新建db.ts 文件

// db.ts
class IndexedDBUtil {
  private dbName: string;
  private storeName: string;
  private dbVersion: number;
  private dbPromise: Promise<IDBDatabase> | null = null;
  
  // 添加固定键名常量
  private readonly DATA_KEY = "complete-dataset";

  constructor(dbName: string, storeName: string, version = 1) {
    this.dbName = dbName;
    this.storeName = storeName;
    this.dbVersion = version;
  }

  // 打开数据库
  private async openDB(): Promise<IDBDatabase> {
    if (this.dbPromise) {
      return this.dbPromise;
    }

    this.dbPromise = new Promise((resolve, reject) => {
      const request = indexedDB.open(this.dbName, this.dbVersion);

      request.onupgradeneeded = (event) => {
        const db = request.result;
        
        if (!db.objectStoreNames.contains(this.storeName)) {
          // 创建对象存储空间 - 无需 keyPath
          const store = db.createObjectStore(this.storeName);
          console.log(`对象存储 ${this.storeName} 创建成功`);
          
          // 添加索引(可选)
          store.createIndex("timestamp", "timestamp", { unique: false });
        }
      };

      request.onsuccess = (event) => {
        console.log('数据库打开成功');
        resolve(request.result);
      };

      request.onerror = (event) => {
        console.error('数据库打开失败:', request.error);
        reject(request.error);
      };
    });

    return this.dbPromise;
  }

  // 保存整个数组
  async saveCompleteData(data: any[]): Promise<void> {
    try {
      const db = await this.openDB();
      const tx = db.transaction(this.storeName, "readwrite");
      const store = tx.objectStore(this.storeName);
      
      // 创建包含数组和时间戳的数据对象
      const dataToStore = {
        dataArray: data,
        timestamp: new Date().toISOString(),
        count: data.length
      };
      
      // 使用固定键名存储整个数据对象
      const request = store.put(dataToStore, this.DATA_KEY);
      
      return new Promise<void>((resolve, reject) => {
        request.onsuccess = () => {
          console.log(`成功存储 ${data.length} 条数据`);
          resolve();
        };
        
        request.onerror = () => {
          console.error('存储数据失败:', request.error);
          reject(request.error);
        };
      });
    } catch (error) {
      console.error('保存数据失败:', error);
      throw error;
    }
  }

  // 获取整个数组
  async getCompleteData(): Promise<any[]> {
    try {
      const db = await this.openDB();
      const tx = db.transaction(this.storeName, "readonly");
      const store = tx.objectStore(this.storeName);
      
      return new Promise<any[]>((resolve, reject) => {
        const request = store.get(this.DATA_KEY);
        
        request.onsuccess = () => {
          if (request.result) {
            console.log(`获取到 ${request.result.count} 条数据`);
            resolve(request.result.dataArray || []);
          } else {
            console.log('未找到存储的数据');
            resolve([]);
          }
        };
        
        request.onerror = () => {
          console.error('获取数据失败:', request.error);
          reject(request.error);
        };
      });
    } catch (error) {
      console.error('获取数据失败:', error);
      return [];
    }
  }
  
  // 检查数据是否存在
  async hasData(): Promise<boolean> {
    const data = await this.getCompleteData();
    return data.length > 0;
  }
}

// 创建实例
export const activityDB = new IndexedDBUtil("ActivityDBStore", "personInfo");

 在需要存储的文件

// 在需要数据的组件/模块中
import { activityDB } from '@/db';
// 请求接口完成后 存储数据
 // 保存到IndexedDB
 await activityDB.saveCompleteData(res);
 
 
// 在需要数据的组件/模块中
import { activityDB } from '@/db';
 
let res = await activityDB.getCompleteData();
posted @ 2025-07-24 14:46  夕露炊烟  阅读(13)  评论(0)    收藏  举报