随着浏览器功能加强,许多网站开始将大量数据保存在客户端,从而减小从服务器获取数据的操做,提升了响应速度。
cookie 因为大小不超过 4kb,确定不合适。
LocalStorage 大小在 2.5 - 10 M间(不一样浏览器不一样,好比Chrome为 5M),且不提供索引、查找慢,也不合适。
IndexedDB 就比较合适了,是浏览器提供的本地数据库,它能够被网页脚本建立和操做。IndexedDB 容许储存大量数据,提供查找接口,还能创建索引提升查询效率。javascript
(1)采用键值对存储。
IndexedDB 内部采用对象仓库(object store)存放数据。全部类型的数据均可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存。html
(2)异步处理。
IndexedDB 操做时采用异步处理,用户能够进行其它操做。vue
(3)支持事务。
IndexedDB 支持事务,即要么完成、要么失败,不会出现完成一半的状态。java
(4)存储空间大、且支持二进制存储。web
(1)数据库(IDBDatabase 对象)
管理、存储数据的仓库。IndexedDB 数据库有版本的概念。同一个时刻,只能有一个版本的数据库存在。若是要修改数据库结构(新增或删除表、索引或者主键),只能经过升级数据库版本完成。vue-cli
(2)对象仓库(IDBObjectStore 对象)
每一个数据库都包含若干对象仓库。能够理解为一个个数据表。数据库
(3)数据记录
对象仓库中存储的即为数据记录,采用键值对保存。其中键惟一,值能够为任意类型。数组
(4)索引(IDBIndex 对象)
为了提升查询效率,能够根据数据记录的主键创建索引。浏览器
(5)事务(IDBTransaction 对象)
数据记录的读写和删改,都要经过事务完成。事务对象提供error、abort和complete三个事件,用来监听操做结果。服务器
(6)操做请求(IDBRequest 对象)
(7)指针( IDBCursor 对象)
可用于遍历数据。
(8)主键集合(IDBKeyRange 对象)
(1)项目目录结构
使用vue-cli建立项目。参考:https://www.cnblogs.com/l-y-h/p/11241503.html
(2)完整代码
此处,我将建立一个 “test” 数据库, 其中有一个 “person” 表(对象仓库) 【main.js】 import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app') 【App.vue】 <template> <div> <small>添加前请先打开数据库(如数据库不存在则执行建立过程)</small><br /><br /> <button @click="openDB">打开数据库</button> <button @click="deleteDB">删除数据库</button><br /><br /> <button @click="closeDB">关闭数据库</button><br /><br /> 姓名:<input type="text" id="name" v-model="name"><br /> 年龄:<input type="number" id="age" min=1 v-model="age"><br /> 性别: 男:<input type="radio" id="man" name="sex" value="male" v-model="sex"> 女:<input type="radio" id="woman" name="sex" value="female" v-model="sex"><br /> <button @click="add">添加数据</button> <button @click="get">获取数据</button><br /> <button @click="foreach">遍历数据</button><br /> <button @click="update">更新数据</button><br /> <button @click="remove">删除数据</button><br /> <button @click="searchFromIndex">根据索引查数据</button><br /> </div> <!--App --> </template> <script> import indexedDB from './indexedDB.js' export default { data () { return { name: 'tom', age: '12', sex: 'male' } }, methods: { openDB() { indexedDB.openDB('test', 'person', 1) }, deleteDB() { indexedDB.deleteDB('test') }, closeDB() { indexedDB.closeDB('test') }, add() { indexedDB.add('person', {name: this.name, age: this.age, sex: this.sex}) }, get() { indexedDB.get('person') }, foreach() { indexedDB.foreach('person') }, update() { indexedDB.update('person', {id: 4, name: this.name, age: this.age, sex: this.sex}) }, remove() { indexedDB.remove('person', 4) }, searchFromIndex() { indexedDB.searchFromIndex('person', 'name', 'tom') } } } </script> <style> </style> 【indexedDB.js】 // 定义一个全局变量,用于保存数据库链接(开发中应该不会这么写,此处只是帮助理解) let db = null; export default { // indexedDB兼容 indexedDB: window.indexedDB || window.webkitindexedDB || window.msIndexedDB || mozIndexedDB, // 打开数据库 // dbname指的是 数据库名, version 指的是 版本号 openDB(dbname, objectStoreName, version) { // 获取当前数据库版本号 var version = version || 1 // 获取数据库链接,若数据库不存在,会建立数据库(异步处理,根据状况自动触发下面三个事件) var request = this.indexedDB.open(dbname, version) // 获取数据库链接失败 request.onerror = function(event) { console.log('IndexedDB数据库打开错误') } // 获取数据库链接成功 request.onsuccess = function(event, callback) { db = event.target.result; if (callback && (typeof callback === 'function')) { callback(db) } if (db != null) { console.log('数据库打开成功') } } // 建立新的储存空间(当第一次建立数据库、或者数据库版本号变化时会触发) request.onupgradeneeded = function(event) { console.log('数据库版本变化') console.log('建立数据库' + dbname) // 拿到数据库链接的结果对象 db = event.target.result; // 判断当前数据库中表(对象仓库)是否存在(注意此处是数据库的表名,不是数据库名) if (!db.objectStoreNames.contains(objectStoreName)) { // 建立对象仓库,并设置主键自增 var objectStore = db.createObjectStore(objectStoreName, { keyPath: 'id', autoIncrement: true }) // 建立索引(根据须要建立) objectStore.createIndex('name', 'name', { unique: false }) objectStore.createIndex('age', 'age', { unique: false }) objectStore.createIndex('sex', 'sex', { unique: false }) } } }, // 删除数据库 deleteDB: function(dbname, callback) { // 删除数据库 var deleteQuest = this.indexedDB.deleteDatabase(dbname); // 成功删除 deleteQuest.onerror = function() { console.log('删除数据库出错' + event.target.message) } // 删除失败 deleteQuest.onsuccess = function() { if (callback && (typeof callback === 'function')) { callback() } console.log('删除数据库成功') } }, // 关闭数据库 closeDB: function() { if (db != null) { db.close() db = null console.log("数据库关闭") } }, // 添加数据 // 对象仓库(表名),传入的参数 add: function(objectStoreName, argument) { if (db != null) { console.log(db) // 执行事务,添加数据到对象仓库(表) var request = db.transaction([objectStoreName], 'readwrite') .objectStore(objectStoreName) .add(argument); request.onsuccess = function(event) { console.log('数据写入成功'); }; request.onerror = function(event) { console.log('数据写入失败'); } } }, // 获取数据 // 对象仓库(表名) get: function(objectStoreName) { if (db != null){ console.log(db) // 执行事务,从对象仓库(表)中获取全部数据 var request = db.transaction([objectStoreName], 'readwrite') .objectStore(objectStoreName).getAll() // 数据获取失败 request.onerror = function(event) { console.log('事务失败') } //数据获取成功 request.onsuccess = function(event) { if (request.result) { // 打印全部数据 console.log(request.result) } else { console.log('未得到数据记录') } }; } }, // 遍历数据 // 对象仓库(表名) foreach: function(objectStoreName) { if (db != null){ console.log(db) // 执行事务,从对象仓库(表)中获取全部数据 var request = db.transaction([objectStoreName], 'readwrite') .objectStore(objectStoreName).openCursor() // 数据获取失败 request.onerror = function(event) { console.log('事务失败') } //数据获取成功 request.onsuccess = function(event) { let cursor = request.result if (cursor) { // 遍历打印全部数据 console.log(cursor) console.log(cursor.key) console.log(cursor.value.name) console.log(cursor.value.age) console.log(cursor.value.sex) cursor.continue() } else { console.log('未得到数据记录') } }; } }, // 更新数据(若数据存在,则覆盖以前的数据,若数据不存在,则新增一个值) // 对象仓库(表名) update: function(objectStoreName, argument) { if (db != null) { console.log(db) // 执行事务,添加数据到对象仓库(表) var request = db.transaction([objectStoreName], 'readwrite') .objectStore(objectStoreName) .put(argument); request.onsuccess = function(event) { console.log('数据更新成功'); }; request.onerror = function(event) { console.log('数据更新失败'); } } }, // 删除数据(若数据不存在,则不会执行删除操做) // 对象仓库(表名) remove: function(objectStoreName, index) { if (db != null){ console.log(db) // 执行事务,从对象仓库(表)中获取全部数据 var request = db.transaction([objectStoreName], 'readwrite') .objectStore(objectStoreName).delete(index) // 数据获取失败 request.onerror = function(event) { console.log('事务失败') } //数据获取成功 request.onsuccess = function(event) { if (request.result) { // 遍历打印全部数据 console.log(request.result) } else { console.log('未得到数据记录') } }; } }, // 根据索引查值(若数据不存在,返回一个[]数组) // 对象仓库(表名) searchFromIndex: function(objectStoreName, index, data) { if (db != null){ console.log(db) // 执行事务,从对象仓库(表)中获取全部数据 var request = db.transaction([objectStoreName], 'readonly') .objectStore(objectStoreName).index(index).getAll(data) // 数据获取失败 request.onerror = function(event) { console.log('事务失败') } //数据获取成功 request.onsuccess = function(event) { if (request.result) { // 遍历打印全部数据 console.log(request.result) } else { console.log('未得到数据记录') } }; } } }
(3)截图:
step1:初始化页面。
step2:点击 打开数据库。
step3:点击添加按钮
step4:改变数据后,再次添加
step5:获取数据(控制台打印)
step6:点击遍历数据按钮
step7:更新数据
以更新id=4为例,此时数据不存在,会新增。
当修改数据后,再次更新,则会覆盖原数据。
step8:根据 name 查询全部 为 tom 的数据。
step9:删除第4条数据(根据主键来删,若主键不存在,则不会删除)。
先获取当前数据。
执行删除后,会删除id=4(id是主键)的数据。
step10:关闭、删除数据库
若先点击 删除按钮,再点击关闭按钮,则删除按钮会等关闭按钮执行后再执行。
此时,test数据库被删除。
(4)建立、打开数据库
需使用 indexedDB.open() 方法,返回一个 IDBRequest 对象,并可能触发三个事件(onsuccess 、onerror、onupgradeneeded )。
【格式:】
var request = window.indexedDB.open(databaseName, version);
【其中:】
databaseName :为字符串,表示数据库名,不可省略。
version : 为当前数据库版本,当数据库不存在时,会建立数据库,且默认为1。
当数据库存在时,若 version 大于当前数据库版本,则会触发数据库升级操做。
当version 省略时,默认为当前数据库版本。
【可能会触发的事件】
onsuccess 表示成功打开数据库。
onerror 表示打开数据库失败。
onupgradeneeded 表示数据库升级事件。当数据库不存在,或者数据库指定版本号大于当前版本时触发。
【代码:】
// 打开数据库
// dbname指的是 数据库名, version 指的是 版本号
openDB(dbname, objectStoreName, version) {
// 获取当前数据库版本号
var version = version || 1
// 获取数据库链接,若数据库不存在,会建立数据库(异步处理,根据状况自动触发下面三个事件)
var request = this.indexedDB.open(dbname, version)
// 获取数据库链接失败
request.onerror = function(event) {
console.log('IndexedDB数据库打开错误')
}
// 获取数据库链接成功
request.onsuccess = function(event, callback) {
db = event.target.result;
if (callback && (typeof callback === 'function')) {
callback(db)
}
if (db != null) {
console.log('数据库打开成功')
}
}
// 建立新的储存空间(当第一次建立数据库、或者数据库版本号变化时会触发)
request.onupgradeneeded = function(event) {
console.log('数据库版本变化')
console.log('建立数据库' + dbname)
// 拿到数据库链接的结果对象
db = event.target.result;
// 判断当前数据库中表(对象仓库)是否存在(注意此处是数据库的表名,不是数据库名)
if (!db.objectStoreNames.contains(objectStoreName)) {
// 建立对象仓库,并设置主键自增
var objectStore = db.createObjectStore(objectStoreName, {
keyPath: 'id',
autoIncrement: true
})
// 建立索引(根据须要建立)
objectStore.createIndex('name', 'name', {
unique: false
})
objectStore.createIndex('age', 'age', {
unique: false
})
objectStore.createIndex('sex', 'sex', {
unique: false
})
}
}
}
(5)添加数据
向对象仓库(表)中写入数据记录。须要经过事务完成。
注意:
db以前已经声明过全局了,这里直接用(实际开发中应该不容许直接声明,能够经过回调函数来实现,有时间再补充)。
建立一个事务须要根据 对象仓库名(表名)以及操做模式(readwrite, readonly),建立事务后,经过IDBTransaction.objectStore(name)方法,拿到 IDBObjectStore 对象,再经过表格对象的add()方法,向表格写入一条记录。
// 添加数据
// 对象仓库(表名),传入的参数
add: function(objectStoreName, argument) {
if (db != null) {
console.log(db)
// 执行事务,添加数据到对象仓库(表)
var request = db.transaction([objectStoreName], 'readwrite')
.objectStore(objectStoreName)
.add(argument);
request.onsuccess = function(event) {
console.log('数据写入成功');
};
request.onerror = function(event) {
console.log('数据写入失败');
}
}
},
(6)读取数据
须要事务来操做。
能够objectStore.get(index)、objectStore.getAll()方法用于读取数据,参数index是主键的值。
// 获取数据
// 对象仓库(表名)
get: function(objectStoreName) {
if (db != null){
console.log(db)
// 执行事务,从对象仓库(表)中获取全部数据
var request = db.transaction([objectStoreName], 'readwrite')
.objectStore(objectStoreName).getAll()
// 数据获取失败
request.onerror = function(event) {
console.log('事务失败')
}
//数据获取成功
request.onsuccess = function(event) {
if (request.result) {
// 打印全部数据
console.log(request.result)
} else {
console.log('未得到数据记录')
}
};
}
},
(7)遍历数据
须要事务来操做。
遍历数据表格的全部记录,要使用指针对象 IDBCursor,使用objectStore.openCursor()获取。
// 遍历数据
// 对象仓库(表名)
foreach: function(objectStoreName) {
if (db != null){
console.log(db)
// 执行事务,从对象仓库(表)中获取全部数据
var request = db.transaction([objectStoreName], 'readwrite')
.objectStore(objectStoreName).openCursor()
// 数据获取失败
request.onerror = function(event) {
console.log('事务失败')
}
//数据获取成功
request.onsuccess = function(event) {
let cursor = request.result
if (cursor) {
// 遍历打印全部数据
console.log(cursor)
console.log(cursor.key)
console.log(cursor.value.name)
console.log(cursor.value.age)
console.log(cursor.value.sex)
cursor.continue()
} else {
console.log('未得到数据记录')
}
};
}
},
(8)更新数据
须要事务来操做。
使用IDBObjectStore.put(index)方法能够更新数据,若index存在则覆盖,不然新增一个值。
// 更新数据(若数据存在,则覆盖以前的数据,若数据不存在,则新增一个值)
// 对象仓库(表名)
update: function(objectStoreName, argument) {
if (db != null) {
console.log(db)
// 执行事务,添加数据到对象仓库(表)
var request = db.transaction([objectStoreName], 'readwrite')
.objectStore(objectStoreName)
.put(argument);
request.onsuccess = function(event) {
console.log('数据更新成功');
};
request.onerror = function(event) {
console.log('数据更新失败');
}
}
},
(9)删除数据
须要事务来操做。
IDBObjectStore.delete(index)方法用于删除记录,参数index是主键的值。
// 删除数据(若数据不存在,则不会执行删除操做)
// 对象仓库(表名)
remove: function(objectStoreName, index) {
if (db != null){
console.log(db)
// 执行事务,从对象仓库(表)中获取全部数据
var request = db.transaction([objectStoreName], 'readwrite')
.objectStore(objectStoreName).delete(index)
// 数据获取失败
request.onerror = function(event) {
console.log('事务失败')
}
//数据获取成功
request.onsuccess = function(event) {
if (request.result) {
// 遍历打印全部数据
console.log(request.result)
} else {
console.log('未得到数据记录')
}
};
}
},
(10)使用索引
须要事务来操做。
根据创建的索引能够很方便的查值。IDBObjectStore.index(index)方法用于索引查找,参数index是索引的值。
// 根据索引查值(若数据不存在,返回一个[]数组)
// 对象仓库(表名)
searchFromIndex: function(objectStoreName, index, data) {
if (db != null){
console.log(db)
// 执行事务,从对象仓库(表)中获取全部数据
var request = db.transaction([objectStoreName], 'readonly')
.objectStore(objectStoreName).index(index).getAll(data)
// 数据获取失败
request.onerror = function(event) {
console.log('事务失败')
}
//数据获取成功
request.onsuccess = function(event) {
if (request.result) {
// 遍历打印全部数据
console.log(request.result)
} else {
console.log('未得到数据记录')
}
};
}
}
(11)删除数据库(会等事务结束再执行)
// 删除数据库
deleteDB: function(dbname, callback) {
// 删除数据库
var deleteQuest = this.indexedDB.deleteDatabase(dbname);
// 成功删除
deleteQuest.onerror = function() {
console.log('删除数据库出错' + event.target.message)
}
// 删除失败
deleteQuest.onsuccess = function() {
if (callback && (typeof callback === 'function')) {
callback()
}
console.log('删除数据库成功')
}
},
(12)关闭数据库
// 关闭数据库
closeDB: function() {
if (db != null) {
db.close()
db = null
console.log("数据库关闭")
}
},
浏览器原生提供indexedDB对象,做为开发者的操做接口。
用于打开数据库。是一个异步操做,可是会当即返回一个IDBOpenDBRequest 对象。
打开一个名为test、版本为1的数据库。若是该数据库不存在,则会新建该数据库。
var openRequest = window.indexedDB.open('test', 1);
触发事件:
success:打开成功。
error:打开失败。
upgradeneeded:第一次打开该数据库,或者数据库版本发生变化。
在success中,能够经过openRequest.result属性拿到已经打开的IndexedDB数据库对象。
在upgradeneeded中,能够传入event,经过 event.target.result 拿到已经打开的IndexedDB数据库对象。
用于删除数据库,是一个异步操做,但会马上返回一个IDBOpenDBRequest对象。
删除名为test的数据库。若数据库不存在,不会报错。
var DBDeleteRequest = window.indexedDB.deleteDatabase('test');
触发事件:
success:删除成功。
error:删除失败。
未完待续。。。
参考地址: https://wangdoc.com/javascript/bom/indexeddb.html