学习IndexDB

162 阅读3分钟

学习IndexDB

IndexDB作为一个很早就已经被广泛支持的浏览器存储API,因为其不如其他存储方式更加简单易用,所以一直不受到前端开发人员的青睐。不过它也有它的优势,存储容量大、内容格式广便是IndexDB值得关注的地方。

创建一个数据库

与其说是创建,不如说是开启一个数据库

const request = window.indexedDB.open("MyTestDatabase");

创建一个表

只能在requestonupgradeneeded中创建,触发该事件的方式是增加数据库版本号

/**
 * 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