VUE

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

原文地址:https://www.cnblogs.com/1285026182YUAN/p/15305466.html