阅读 194

TagDown 扩展程序开发——前端数据持久化之 Dexie.js

TagDown 是一款开源的书签管理插件, 您可以使用扩展程序浏览新增修改书签,它也支持以不同方式导出书签。

除了常见的书签管理功能,还具有以下特点:

  • 支持 ???? 新增书签,并附加额外的信息,例如 tagsgroups

  • 支持 ???? 导出任意书签为 json 文档

  • 以 ???? 树图的形式浏览层级结构的书签数据

  • 一键打开多个书签,支持在 ???? 标签组内打开书签


虽然 IndexedDB 大部分操作都是异步的,但是方法返回的不是 Promise,而是基于监听事件执行回调的方式来处理操作结果,开发繁琐且代码不易于维护。

为了便于开发使用一个名为 Dexie.js 库,它对 IndexedDB APIs 进行二次封装,让调用 IndexedDB 更方便。该库大部分方法都是异步且返回 Promise。

与 IndexedDB 类似,它也有相应的不同概念,且不同的类封装了不同的方法

  • Dexie 该库的核心类,通过该类实例化,可以创建/连接一个 IndexedDB 数据库

  • Table 该类表示对象库 ObjectStore

  • Collection 该类表示对象库中一部分数据项,可以理解为数据的查询结果

// src/ // 实例化一个数据库 const db = new Dexie('tagdown'); // 声明版本和数据结构(对象库) db.version(1).stores({   // 创建 3 个对象库,键为对象库的名称,值是对象库的中数据项的键和索引,用逗号分隔   bookmark: 'id, *tags, *groups', // 第一个是指定用作为键的属性,之后就是索引   // 加星号 * 表示数据相应属性值为数组,且将数组的每个元素作为索引   share: 'id, share',   star: 'id, star', }); // 打开/创建数据库,异步操作 db.open().then((database) => {   app.provide('db', database); // 通过 provide-inject 的方式将数据库对象提供给应用中其他组件使用   app.mount('#app'); }).catch((err) => {   // Error occurred   console.log(err); }); 复制代码

???? 根据官方的操作指南,不必判断浏览器中是否有已有同名的数据,因为每次尝试连接数据库时,Dexie 会自动判断,按需打开已有数据库或创建一个新数据库。

以下列出在项目中与数据库相关的一些主要方法

// src/composables/useBookmark.js // ... const db = inject('db'); // 基于键 id 查询数据 const getBookmarkDB = async (id) => {   const bookmark = await db.bookmark.get(id);   return bookmark; }; // 向 bookmark 对象库添加数据 const setBookmarkDB = async (id, bookmark) => {   // console.log(bookmark);   await db.bookmark.put({     id,     title: bookmark.title,     url: bookmark.url,     faviconUrl: bookmark.faviconUrl,     tags: bookmark.tags,     groups: bookmark.groups,     description: bookmark.description,   }); }; // 基于键 id 删除数据 const deleteBookmarkDB = async (id) => {   await db.bookmark.delete(id); }; 复制代码

获取索引的所有值

// src/options/App.vue // ... const db = inject('db'); onMounted(async () => {   // 获取数据库中索引 tags 的所有可能的值   allTags.value = await db.bookmark.orderBy('tags').uniqueKeys(); }); 复制代码

使用 where 查询语句

// src/options/App.vue // ... const db = inject('db'); // 筛选条件是索引 share 的值为 1,并返回一个由这些数据的键值构成的数组 const getShareableIds = async () => {   const result = await db.share.where('share').equals(1).primaryKeys();   return result; }; 复制代码

将查询结果转换为数组

// src/popup/components/BrowserPage.vue // ... const db = inject('db'); const starNodes = await db.star.where({ star: 1 }).toArray(); 复制代码

导入、导出 IndexedDB 数据库

// src/options/App.vue // ... import {   importDB, exportDB, importInto, peakImportFile, } from 'dexie-export-import'; // ... // 导出数据库为 blob blob = await exportDB(db, {   prettyJson: true, }); // ... // 导入数据库 await importInto(db, file, {   overwriteValues: true, }).then(() => {   console.log('import database successful!'); }).catch((err) => {   console.log(err); });


作者:Benbinbin
链接:https://juejin.cn/post/7018821423414116365


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐