VUE - IndexDB瀏覽器數據庫做緩存


VUE - IndexDB瀏覽器數據庫做緩存

前端開發時經常有瀏覽器做緩存的需求,但是其他緩存容量都比較小,只有幾K到幾M

如有大數據,或者文件要做緩存存儲在瀏覽器端,則考虛用瀏覽器數據庫IndexDB,存儲無上限。

各緩存比較:https://www.cnblogs.com/ccv2/p/13046768.html

 

1.  本文以 VUE 項目為例,在 app.vue中引入 test2.vue ,調用 utils / uIndexDB.js 工具組件

 

 

 

 

 2. 關鍵代碼

 

1) 定義 indexDB

const indexDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;

 

 

2)  緩存類 IndexDBCache

class IndexDBCache {
  //構造函數
  constructor(callback) {
    this._db = null; //數據庫
    this._transaction = null; //事務
    this._request = null;
    this._dbName = 'cacheModel'; //數據庫名
    this._cacheTableName = 'tabmodalcache'; //表名
    this._dbversion = 1; //數據庫版本 
    this.DB_Init(callback); //初始化數據庫
  }
  ......
  ......
  ...... }

 

 

3) 初始化數據庫

  //初始化數據庫
  DB_Init(callback) {
    debugger;
    this._request = indexDB.open(this._dbName, this._dbversion); //數據庫名,版本
    this._request.onsuccess = event => {
      debugger;
      this._db = this._request.result;
      let msg = 'indexdb打開成功!'
      console.log(msg);
      if (typeof callback === 'function') callback(msg);
    };
    this._request.onerror = event => {
      debugger;
      let msg = 'indexdb初始化失敗!'
      console.log(msg);
      if (typeof callback === 'function') callback(msg);
    };
    this._request.onupgradeneeded = event => {
      debugger;
      let db = this._request.result;

      if (!db.objectStoreNames.contains(this._cacheTableName)) {
        let store = db.createObjectStore(this._cacheTableName, {
          keyPath: 'id', //設置主鍵
          autoIncrement: true //自動生成主鍵
        });
        //創建索引
        store.createIndex("INDEX_ID", "id", {
          unique: true
        });

        //創建索引
        store.createIndex('index_senceid', 'senceid', {
          unique: false, //true:唯一,false:可重復
        });
      }
      let msg = 'indexdb升級成功!';
      console.log(msg);
      if (typeof callback === 'function') callback(msg);
    }
  }

 

 

4)刪除數據庫

  //刪除數據庫
  DB_Remove(callback) {
    var DBDeleteRequest = indexedDB.deleteDatabase(this._dbName);

    DBDeleteRequest.onerror = function (event) {
      console.log('Error');
    };

    DBDeleteRequest.onsuccess = function (event) {
      let msg = 'indexdb刪除成功!';
      console.log(msg);
      if (typeof callback === 'function') callback(msg);
    };
  }

 

 

5) 關閉數據庫

  //關閉數據庫
  DB_Close() {
    this._db.close();
  }

 

 

6) 獲取表

  //獲取表
  Table_Get() {
    return new Promise((resolve, reject) => {
      resolve(this._db.objectStoreNames);
    });
  }

 

 

7) 新增數據

  /** 新增數據 
   * obj: {path:'Http://xxxxx.com',version:'V1',value:'ccc'}  
   * */
  Record_Add(obj) {

    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
      let store = transaction.objectStore(this._cacheTableName);
      let response = store.add(obj);
      response.onsuccess = (cc, mm) => {

        let msg = `新增數據${JSON.stringify(obj)}`
        resolve(msg);
      }
      response.onerror = (event) => {
        console.log('新增失敗');
        reject(event);
      }
    })
  }

 

 

 8) 獲取數據

  //獲取數據
  Record_Get() {
    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName);
      var objectStore = transaction.objectStore(this._cacheTableName);

      //主健讀取
      // var request = objectStore.get(1);

      //使用索引讀取
      var index = objectStore.index('index_senceid');
      var request = index.get('222');

      request.onsuccess = () => {

        resolve(request.result);
      };

      request.onerror = (event) => {

        console.log('獲取失敗');
        reject(event);
      };
    });
  }

 

 

 9) 獲取所有數據

  //獲取所有數據
  Record_GetAll() {
    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName);
      var objectStore = transaction.objectStore(this._cacheTableName);

      let request = objectStore.getAll();

      request.onsuccess = () => {

        resolve(request.result);
      };

      request.onerror = (event) => {

        console.log('獲取失敗');
        reject(event);
      };
    })
  }

 

 

10) 更新數據

  /** 更新數據
   * obj: {path:'Http://xxxxx.com',version:'V1',value:'fff'}  
   */
  Record_Update(obj) {
    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
      let store = transaction.objectStore(this._cacheTableName);
      var request = store.put(obj);
      request.onsuccess = function (event) {

        let msg = '數據更新成功';
        console.log(msg);
        resolve(msg);
      };

      request.onerror = function (event) {

        console.log('數據更新失敗');
        reject(event);
      }
    });
  }

 

 

 11) 刪除數據

  //刪除數據
  Record_Remove(id) {
    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
      let store = transaction.objectStore(this._cacheTableName);
      let response = store.delete(id);
      response.onsuccess = () => {
        console.log('刪除成功');
        resolve('刪除成功');
      }
      response.onerror = (event) => {
        console.log('刪除失敗');
        reject(event);
      }
    })

  }

 

12) 加載網絡文件,以 blob 格式存儲

  //加載網絡文件
  loadNetSource(url) {
    return new Promise((resolve, reject) => {
      fetch(url).then(res => {
        if (res.status === 200) {
          res.blob().then(blob => {
            resolve(blob);
          })
        } else {
          console.log('未找到緩存資源');
          reject(url);
        }
      })
    })
  }

 

讀取時,使用 URL.createObjectURL() 創建虛擬地址

   let _url = URL.createObjectURL(blob);

 

 

3.  代碼如下

1)  src / APP.vue

<template>
  <div id="app">
    <test></test>
  </div>
</template>

<script>
import test from "./test2.vue";

export default {
  name: "app",
  components: { test },
  data() {
    return {
      msg: "Welcome to Your Vue.js App",
    };
  },
};
</script>

<style>
</style>
View Code

 

 

2) src / test2.vue

<template>
  <div class="box">
    <div class="btnBox">
      <button class="btn" @click="fun_db_close">關閉數據庫</button>
      <button class="btn" @click="fun_db_remove">刪除數據庫</button>
    </div>
    <div class="btnBox">
      <button class="btn" @click="fun_table_create">創建對象倉庫</button>
      <button class="btn" @click="fun_table_remove">刪除對象倉庫</button>
      <button class="btn" @click="fun_table_update">更新對象倉庫</button>
      <button class="btn" @click="fun_table_get">獲取對象倉庫</button>
    </div>

    <div class="btnBox">
      <button class="btn" @click="fun_record_create">寫入記錄</button>
      <button class="btn" @click="fun_record_remove">刪除記錄</button>
      <button class="btn" @click="fun_record_update">更新記錄</button>
      <button class="btn" @click="fun_record_get">獲取記錄</button>
      <button class="btn" @click="fun_record_getall">獲取所有記錄</button>
    </div>
    <div class="infoBox">
      <p class="pInfo" v-for="(item, i) in messages">{{ item }}</p>
    </div>
  </div>
</template>

<script>
import IndexDBCache from "./utils/uIndexDB";
let dbCache = null;

export default {
  data() {
    return {
      messages: [],
    };
  },

  //頁面加載時初始化 indexdb
  mounted() {
    debugger;
    dbCache = new IndexDBCache((msg) => this.supply_message(msg));
  },

  // //頁面銷毀時 關閉數據庫
  // destroyed() {
  //   debugger;
  //   this.fun_db_close();
  // },

  methods: {
    fun_db_close() {
      dbCache.DB_Close();
    },
    //刪除數據庫
    fun_db_remove() {
      dbCache.DB_Remove((msg) => this.supply_message(msg));
    },

    //寫入記錄
    fun_record_create() {
      // let objParam = {
      //   senceid: "111",
      //   version: "V1",
      //   path: "Http://xxxx.com",
      //   value: "aaa",
      // };

      let objParam = {
        senceid: "222",
        version: "V1",
        path: "Http://yyyy.com",
        value: "bbb",
      };
      dbCache.Record_Add(objParam).then((msg) => {
        this.messages.push("寫入: " + msg);
      });
    },
    //刪除記錄
    fun_record_remove() {
      dbCache.Record_Remove(2).then((msg) => {
        this.messages.push("刪除: " + msg);
      });
    },
    //更新記錄
    fun_record_update() {
      let objParam = {
        id: 2,
        senceid: "222",
        version: "V2",
        path: "Http://yyyy-2.com",
        value: "bbb2",
      };
      dbCache.Record_Update(objParam).then((msg) => {
        this.messages.push("更新: " + msg);
      });
    },
    //獲取數據
    fun_record_get() {
      dbCache.Record_Get().then((msg) => {
        this.messages.push("讀取: " + JSON.stringify(msg));
      });
    },
    //獲取所有數據
    fun_record_getall() {
      dbCache.Record_GetAll().then((msg) => {
        this.messages.push("讀取: " + JSON.stringify(msg));
      });
    },
    //創建表
    fun_table_create() {
      this.messages.push(
        "請修改版本號更新數據庫,參考:https://wangdoc.com/javascript/bom/indexeddb.html#indexeddbdeletedatabase"
      );
    },
    //刪除表
    fun_table_remove() {
      this.messages.push(
        "在versionchange中實現 deleteObjectStore 方法 ,參考://wangdoc.com/javascript/bom/indexeddb.html#indexeddbdeletedatabase"
      );
    },
    //更新表
    fun_table_update() {
      this.messages.push(
        "請修改版本號更新數據庫,參考:https://wangdoc.com/javascript/bom/indexeddb.html#indexeddbdeletedatabase"
      );
    },
    //獲取表
    fun_table_get() {
      dbCache.Table_Get().then((msg) => {
        this.messages.push("獲取表: " + JSON.stringify(msg));
      });
    },
    //輸出信息
    supply_message(msg) {
      this.messages.push(msg);
    },
  },
};
</script>

<style scoped>
.box {
  margin: 20px;
}
.btnBox {
  margin: 10px;
}
.btn {
  width: 100px;
  height: 30px;
}

.infoBox {
  min-height: 50px;
  border: 1px solid grey;
  margin: 10px;
  padding: 5px 10px;
}
.pInfo {
  margin: 5px;
}
</style>
View Code

 

 

 3) src / utils / uIndexDB.js

const indexDB = window.indexedDB || window.webkitIndexedDB ||
  window.mozIndexedDB;

class IndexDBCache {
  //構造函數
  constructor(callback) {
    this._db = null; //數據庫
    this._transaction = null; //事務
    this._request = null;
    this._dbName = 'cacheModel'; //數據庫名
    this._cacheTableName = 'tabmodalcache'; //表名
    this._dbversion = 1; //數據庫版本 
    this.DB_Init(callback); //初始化數據庫
  }


  //初始化數據庫
  DB_Init(callback) {

    this._request = indexDB.open(this._dbName, this._dbversion); //數據庫名,版本
    this._request.onsuccess = event => {

      this._db = this._request.result;
      let msg = 'indexdb打開成功!'
      console.log(msg);
      if (typeof callback === 'function') callback(msg);
    };
    this._request.onerror = event => {

      let msg = 'indexdb初始化失敗!'
      console.log(msg);
      if (typeof callback === 'function') callback(msg);
    };
    this._request.onupgradeneeded = event => {

      let db = this._request.result;

      if (!db.objectStoreNames.contains(this._cacheTableName)) {
        let store = db.createObjectStore(this._cacheTableName, {
          keyPath: 'id', //設置主鍵
          autoIncrement: true //自動生成主鍵
        });
        //創建索引
        store.createIndex("INDEX_ID", "id", {
          unique: true
        });

        //創建索引
        store.createIndex('index_senceid', 'senceid', {
          unique: false, //true:唯一,false:可重復
        });
      }
      let msg = 'indexdb升級成功!';
      console.log(msg);
      if (typeof callback === 'function') callback(msg);
    }
  }

  //刪除數據庫
  DB_Remove(callback) {
    var DBDeleteRequest = indexedDB.deleteDatabase(this._dbName);

    DBDeleteRequest.onerror = function (event) {
      console.log('Error');
    };

    DBDeleteRequest.onsuccess = function (event) {
      let msg = 'indexdb刪除成功!';
      console.log(msg);
      if (typeof callback === 'function') callback(msg);
    };
  }

  //關閉數據庫
  DB_Close() {
    this._db.close();
  }

  //獲取表
  Table_Get() {
    return new Promise((resolve, reject) => {
      resolve(this._db.objectStoreNames);
    });
  }

  /** 新增數據 
   * obj: {path:'Http://xxxxx.com',version:'V1',value:'ccc'}  
   * */
  Record_Add(obj) {

    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
      let store = transaction.objectStore(this._cacheTableName);
      let response = store.add(obj);
      response.onsuccess = (cc, mm) => {

        let msg = `新增數據${JSON.stringify(obj)}`
        resolve(msg);
      }
      response.onerror = (event) => {
        console.log('新增失敗');
        reject(event);
      }
    })
  }

  //獲取數據
  Record_Get() {
    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName);
      var objectStore = transaction.objectStore(this._cacheTableName);

      //主健讀取
      // var request = objectStore.get(1);

      //使用索引讀取
      var index = objectStore.index('index_senceid');
      var request = index.get('222');

      request.onsuccess = () => {

        resolve(request.result);
      };

      request.onerror = (event) => {

        console.log('獲取失敗');
        reject(event);
      };
    });
  }

  //獲取所有數據
  Record_GetAll() {
    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName);
      var objectStore = transaction.objectStore(this._cacheTableName);

      let request = objectStore.getAll();

      request.onsuccess = () => {

        resolve(request.result);
      };

      request.onerror = (event) => {

        console.log('獲取失敗');
        reject(event);
      };
    })
  }

  /** 更新數據
   * obj: {path:'Http://xxxxx.com',version:'V1',value:'fff'}  
   */
  Record_Update(obj) {
    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
      let store = transaction.objectStore(this._cacheTableName);
      var request = store.put(obj);
      request.onsuccess = function (event) {

        let msg = '數據更新成功';
        console.log(msg);
        resolve(msg);
      };

      request.onerror = function (event) {

        console.log('數據更新失敗');
        reject(event);
      }
    });
  }

  //刪除數據
  Record_Remove(id) {
    return new Promise((resolve, reject) => {

      let transaction = this._db.transaction(this._cacheTableName, 'readwrite');
      let store = transaction.objectStore(this._cacheTableName);
      let response = store.delete(id);
      response.onsuccess = () => {
        console.log('刪除成功');
        resolve('刪除成功');
      }
      response.onerror = (event) => {
        console.log('刪除失敗');
        reject(event);
      }
    })

  }
}

export default IndexDBCache;
View Code

 

 

4.  測試效果 

 

  

 

 

引用:http://www.ruanyifeng.com/blog/2018/07/indexeddb.html

引用:https://www.jianshu.com/p/9df6989d07f5

引用:https://wangdoc.com/javascript/bom/indexeddb.html#indexeddbdeletedatabase

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM