学习IndexDB
IndexDB作为一个很早就已经被广泛支持的浏览器存储API,因为其不如其他存储方式更加简单易用,所以一直不受到前端开发人员的青睐。不过它也有它的优势,存储容量大、内容格式广便是IndexDB值得关注的地方。
创建一个数据库
与其说是创建,不如说是开启一个数据库
const request = window.indexedDB.open("MyTestDatabase");
创建一个表
只能在request
的onupgradeneeded
中创建,触发该事件的方式是增加数据库版本号
/**
* open方法中传入第二个参数版本号version来触发onupgradeneeded事件
* 只有在version大于上一次的版本号时,才会触发onupgradeneeded事件
*/
const request = window.indexedDB.open("MyTestDatabase", 2);
request.onupgradeneeded = (event) => {
// 只能在这个事件处理中创建,并且仅限这个事件循环中
/** 获取db对象 */
const db = event.target.result;
/**
* 使用db对象创建表,自增key模式
* 这种模式不限制存储数据的类型,比如可以存储blob数据
*/
db.createObjectStore("names", { autoIncrement: true });
/**
* 使用db对象创建表,指定唯一key,该例中使用ssn字段作为唯一key
* 这种模式限制存储对象为object类型,并且要有唯一的ssn属性值
*/
db.createObjectStore("customers", { keyPath: "ssn" });
};
获取db对象
在request.onsucess
事件处理程序中获取db
对象,db
对象可用于创建事务,并且可以存起来,供后续使用
let db;
// onsuccess中获取db
request.onsuccess = (event) => {
// 获取db
db = event.target.result;
// 刷新数据
refreshData();
};
添加一个数据
使用db
对象创建一个transcation
事务对象,transaction
再创建
/** 唯一id,会递增 */
let ssn = 0;
// 点击事件中存储一个值
document.getElementById("add").addEventListener("click", add);
function add() {
/** 名字输入框 */
const nameInput = document.getElementById("name");
// 获取事务对象
// customers表示事务需操作的表
// readwrite表示读写权限
const transaction = db.transaction("customers", "readwrite");
// 监听事务是否完成
transaction.oncomplete = () => {
nameInput.value = "";
refreshData();
};
// 获取操作customers表数据的对象
const customersStore = transaction.objectStore("customers");
/**
* customers表中添加一个值
* 其中ssn是必须且唯一的,因为在创建customers表示设定了ssn作为唯一key键
* 除此之外,可以增加和删除任意的属性,不需要重新定义table
* 可以理解为就是存了一个object数据
*/
customersStore.add({
ssn: String(ssn++),
name: nameInput.value,
});
}
遍历数据并展示
function refreshData() {
/** 存放列表数据 */
const list = [];
const transaction = db.transaction("customers");
const customersStore = transaction.objectStore("customers");
transaction.oncomplete = () => {
/** 对列表数据进行排序 */
list.sort((a, b) => (Number(a.ssn) > Number(b.ssn) ? 1 : -1));
/** 渲染列表数据 */
renderList(list);
/** 更新缓存的ssn值 */
updateSsn(list);
};
/**
* 使用openCursor方法去遍历表中的数据
*/
customersStore.openCursor().onsuccess = (event) => {
/**
* 获取cursor对象
* cursor有key和value两个属性值,是比较常用到的
* key就是唯一键的值
* value是存储的数据
*/
const cursor = event.target.result;
if (cursor) {
/** 将数据存入list中 */
list.push(cursor.value);
/** 遍历下一个数据 */
cursor.continue();
} else {
/** 没有cursor,则表示遍历结束了 */
console.log("没有更多数据了");
}
};
}
获取并修改数据
function putCustomer(item) {
const newName = prompt("请输入新名字");
if (newName) {
const transaction = db.transaction("customers", "readwrite");
transaction.oncomplete = () => {
refreshData();
};
const customersStore = transaction.objectStore("customers");
// 使用get方法并传入唯一key值,获取对象数据
const request = customersStore.get(item.ssn);
// 成功后可以拿到数据
request.onsuccess = (event) => {
// 拿到数据
const data = event.target.result;
// 没有对应的key数据,则会拿到一个undefined
if (data) {
data.name = newName;
// 使用put方法即可以将数据存入
customersStore.put(data);
}
};
}
}
删除数据
function deleteCustomer(item) {
const result = confirm("确认删除吗");
if (result) {
const transaction = db.transaction("customers", "readwrite");
transaction.oncomplete = () => {
refreshData();
};
const customersStore = transaction.objectStore("customers");
/**
* 调用delete方法删除数据
* 删除不存在的key不会报错
*/
customersStore.delete(item.ssn);
}
}
完整示例地址
以上内容只是简单展示了IndexDB
的用法,详情可阅读MDN Using IndexDB