前端超大缓存IndexDB、入门及实际使用

文章目录

  • 往期回顾
  • 项目实战
    • 初始化表
    • 获取列表
    • 新增表的数据项
    • 获取详情
      • 根据ID获取详情
      • 根据其他字段获取详情
    • 删除数据
  • 总结

往期回顾

在这里插入图片描述

在之前的文章中,我们介绍了IndexDB vs Cookies vs Session这几个的对比,但是没有做实际项目的演示,今天我们用实际项目来演示IndexDB的便捷性。

首先需要明确的是IndexDB的适用场景:

  • 离线应用
  • 大型网页游戏
  • 数据缓存
  • 复杂数据管理和查询

项目实战

我们用纯IndexDB来实现表格的基本增删改查的功能!

这只是一个引子,实际上你可以将本示例的思想用于更大的场景
在这里插入图片描述

初始化表

按如下代码格式初始化IndexDB,如果初始不存在,则创建表CryptSetting(实际名称可自定义)和表的字段名,如下objectStore.createIndex()方法。

创建表是最好声明一个自增的唯一主键id,本例为projectId

let db = null;
// 初始化indexDB数据库
async function initDB() {const request = window.indexedDB.open('CryptSetting', 1);// success 事件表示成功打开数据库request.onsuccess = (event) => {db = event.target.result;// 打开成功之后需要获取数据库列表getList()};// error 事件表示打开数据库失败request.onerror = (event) => {console.log('打开 IndexedDB 失败');};// 如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件 upgradeneededrequest.onupgradeneeded = function (e) {db = e.target.result;let objectStore;if ( !db.objectStoreNames.contains('CryptSetting') ) {// 索引名称、索引所在的属性、配置对象(说明该属性是否包含重复的值)objectStore = db.createObjectStore('CryptSetting', { keyPath: 'projectId', autoIncrement: true });objectStore.createIndex('project_name', 'projectName', { unique: false });objectStore.createIndex('key_1', 'key', { unique: false });objectStore.createIndex('iv_1', 'iv', { unique: false });}};
}

初始化之后,会在控制台看到如下:
在这里插入图片描述

获取列表

初始化之后,需要获取数据库列表

请注意以下的写法,列表只能一条条获取,可以先声明一个空数组接收,最后统一赋值
此处用到了continue方法
效率还是很快的,不要以为一条条获取速度就慢!

// 获取配置列表
async function getList() {loading.value = trueconst transaction = db.transaction([ 'CryptSetting' ], 'readonly');const objectStore = transaction.objectStore('CryptSetting');const request = objectStore.openCursor(); // 获取所有配置// indexDB是一个个获取数据的,所以用数组接收,最后统一赋值const tempArr = []request.onsuccess = function (event) {const cursor = event.target.result;if (cursor) {tempArr.push(cursor.value);cursor.continue(); // 继续遍历下一条数据} else {tableData.value = tempArrloading.value = false}};request.onerror = function () {errorTip('获取列表失败')loading.value = false};
}

新增表的数据项

表初始化之后,其实还是空的表,所以上面获取值为空,所以此时需要往里面添加数据,按如下格式写即可。

注意:此处不传projectId,因为它是主键ID、会自动生成,按123456,
如果6被删除了,下次自动生成的ID为7

function addSettings() {const transaction = db.transaction([ 'CryptSetting' ], 'readwrite');const objectStore = transaction.objectStore('CryptSetting');const { projectName, key, iv } = formData.value // 此处不传projectId,自动生成const request = objectStore.add({projectName,key,iv});request.onsuccess = function (event) {successTip('添加成功')};request.onerror = function (event) {errorTip()};
}

新增之后,效果如下:在这里插入图片描述

获取详情

根据ID获取详情

// 获取配置详情
function getSettingsDetail(id) {const transaction = db.transaction([ 'CryptSetting' ], 'readonly');const objectStore = transaction.objectStore('CryptSetting');const request = objectStore.get(id);request.onsuccess = function (event) {const result = event.target.result;if (result) {title.value = '编辑项目配置'isEdit.value = truedialogVisible.value = trueformData.value = result} else {errorTip('获取失败')}};request.onerror = function(event) {}
}

根据其他字段获取详情

在 IndexedDB 中,get 方法只能根据主键(keyPath)来查询数据。如果你需要根据其他字段(如 projectName、key、iv 等)来查询数据,可以使用索引(index)。索引允许你根据非主键字段来查询数据。
以下示例为:根据 projectName 查询配置详情

function getSettingsByProjectName(projectName) {console.log('projectName', projectName);const transaction = db.transaction(['CryptSetting'], 'readonly');const objectStore = transaction.objectStore('CryptSetting');const index = objectStore.index('project_name');const request = index.get(projectName);request.onsuccess = function (event) {const result = event.target.result;if (result) {title.value = '编辑项目配置';isEdit.value = true;dialogVisible.value = true;formData.value = result;} else {errorTip('获取失败');}};request.onerror = function (event) {console.error('查询失败', event);errorTip('查询失败');};
}

删除数据

// 删除配置,传参id
function deleteSettings(id) {const transaction = db.transaction([ 'CryptSetting' ], 'readwrite');const objectStore = transaction.objectStore('CryptSetting');const request = objectStore.delete(id); // 假设我们要删除id的记录request.onsuccess = function (event) {successTip('删除成功');};request.onerror = function (event) {errorTip('删除失败');};
}

总结

IndexDB的许多思想都和mysql有相似之处。
我们发现,基本上增删改查都有相似的代码

  const transaction = db.transaction(['CryptSetting'], 'readwrite');const objectStore = transaction.objectStore('CryptSetting');

其实这段代码是不能省略的,因为它:

  • 事务的独立性:
    • 每个事务都是独立的,不能共享。一旦事务完成,就不能再使用它。
    • 如果尝试在多个操作中重用同一个事务,会导致错误。
  • 数据一致性:
    • 每个事务确保数据的一致性。如果多个操作共享同一个事务,一个操作失败会导致整个事务回滚,影响其他操作。
  • 错误隔离:
    • 每个事务有自己的错误处理机制。如果一个事务失败,其他事务不会受到影响。
    • 通过每次操作声明新的事务,可以更好地控制错误处理和回滚。

为了确保数据操作的正确性和一致性,每次进行新增、删除、更新等操作时都需要声明新的 transaction 和 objectStore。这是 IndexedDB 的设计原则,确保每个操作都是独立且可靠的。因此,不能省略每次操作时的 transaction 和 objectStore 声明。

以上仅为简易的入门,及细节讲解,更多细节需要实战中探索,感谢打赏!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/498548.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

swiftui开发页面加载发送请求初始化@State变量

在SwiftUI中,你不能直接在init中更新State变量,因为State是由SwiftUI框架管理的,初始化时不允许直接修改。所以需要在onAppear发送请求然后修改State状态。 在SwiftUI中,如果希望在页面加载时立即发送网络请求,可以使…

OpenStack系列第四篇:云平台基础功能与操作(Dashboard)

文章目录 1. 镜像(Image)添加镜像查看镜像删除镜像 2. 卷(Volume)创建卷查看卷删除卷 3. 网络(虚拟网络)创建网络查看网络删除网络 4. 实例类型创建实例类型查看实例类型删除实例类型 4. 密钥对&#xff08…

3D数学基础2

矩阵的行列式 在任意方阵中都存在至少一个标量,称作该方阵的行列式。在线性代数中,行列式有很多有用的性质 线性运算法则 方阵 M M M的行列式记作 ∣ M ∣ |M| ∣M∣或“det M”。非方阵矩阵的行列式是未定义的。 注意,在书写行列式时&…

elementui的默认样式修改

今天用element ui ,做了个消息提示,发现提示的位置总是在上面,如图: 可是我想让提示的位置到下面来,该怎么办? 最后还是看了官方的api 原来有个自定义样式属性 customClass 设置下就好了 js代码 css代码…

WebRTC:实现浏览器与移动应用的实时通信

1.技术简介 (Web Real-Time)是一种开放式实时通信技术,旨在使浏览器和移动应用程序通过简单的API即可实现实时音频、视频和数据传输,而无需安装插件或额外软件。它支持网络应用中的点对点通信,例如视频聊天、语音通话…

NVR小程序接入平台EasyNVR使用FFmpeg取流时提示错误是什么原因呢?

在视频监控系统中,FFmpeg常用于从各种源(如摄像头、文件、网络流等)获取流媒体数据,这个过程通常称为“取流”。 在EasyNVR平台中,使用FFmpeg取流是一种常见的操作。FFmpeg作为一款强大的开源多媒体处理工具&#xff…

NXP i.MX8系列平台开发讲解 - 5.4 调试篇 - 掌握perf 工具调试(一)

专栏文章目录传送门:返回专栏目录 Hi, 我是你们的老朋友,主要专注于嵌入式软件开发,有兴趣不要忘记点击关注【码思途远】 文章目录 目录 掌握perf 工具调试(一) 1. Perf 工具介绍 1.1 Perf 工作原理 1.2 Perf 工具基本功能 2. Perf 安…

实际部署Dify可能遇到的问题:忘记密码、开启HTTPS、知识库文档上传的大小限制和数量限制

背景 前面我们以 docker compose 容器化的方式本地部署了 Dify 社区版,并快速体验了其聊天助手、工作量编排以及智能体(Agent)功能。不过后续实际生产环境使用时遇到了忘记密码、如何开启SSL以支持HTTPS、如何突破知识库文档上传的大小限制和…

Python 青铜宝剑十六维,破医疗数智化难关(上)

一、医疗数智化困境剖析 在当今数智化浪潮的席卷下,医疗行业正经历着深刻变革,医疗数智化转型已成为不可阻挡的趋势。它将现代信息技术深度融入医疗的各个环节,从电子病历的广泛普及,实现医疗信息的便捷存储与快速查阅&#xff0…

Kafka 性能提升秘籍:涵盖配置、迁移与深度巡检的综合方案

文章目录 1.1.网络和io操作线程配置优化1.2.log数据文件刷盘策略1.3.日志保留策略配置1.4.replica复制配置1.5.配置jmx服务1.6.系统I/O参数优化1.6.1.网络性能优化1.6.2.常见痛点以及优化方案1.6.4.优化参数 1.7.版本升级1.8.数据迁移1.8.1.同集群broker之间迁移1.8.2.跨集群迁…

易基因: BS+ChIP-seq揭示DNA甲基化调控非编码RNA(VIM-AS1)抑制肿瘤侵袭性|Exp Mol Med

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 肝细胞癌(hepatocellular carcinoma,HCC)早期复发仍然是一个具有挑战性的领域,其中涉及的机制尚未完全被理解。尽管微血管侵犯&#xff08…

代码随想录算法【Day7】

DAY7 454.四数相加II 特点: 1.只用返回元组的个数,而不用返回具体的元组 2.可以不用去重 暴力思路:遍历,这样时间复杂度会达到O(n^4) 标准思路:用哈希法(场景:在一个集合里面判断一个元素…

[TOTP]android kotlin实现 totp身份验证器 类似Google身份验证器

背景:自己或者公司用一些谷歌身份验证器或者microsoft身份验证器,下载来源不明,或者有广告,使用不安全。于是自己写一个,安全放心使用。 代码已开源:shixiaotian/sxt-android-totp: android totp authenti…

Type c系列接口驱动电路·内置供电驱动电路使用USB2.0驱动电路!!!

目录 前言 Type c常见封装类型 Type c引脚功能详解 Type c常见驱动电路详解 Type c数据手册 ​​​​​​​ ​​​​​​​ 编写不易,仅供学习,请勿搬运,感谢理解 常见元器件驱动电路文章专栏连接 LM7805系列降压芯片驱动电路…

【竞技宝】LOL:IG新赛季分组被质疑

北京时间2024年12月31日,今天已经2024年的最后一天,在进入一月之后,英雄联盟将迎来全新的2025赛季。而目前新赛季第一阶段的抽签结果已经全部出炉,其中人气最高的IG战队在本次抽签中抽到了“绝世好签”引来了网友们的质疑。 首先介…

【大模型实战篇】Mac本地部署RAGFlow的踩坑史

1. 题外话 最近一篇文章还是在11月30日写的,好长时间没有打卡了。最近工作上的事情特别多,主要聚焦在大模型的预训练、微调和RAG两个方面。主要用到的框架是Megatron-DeepSpeed,后续会带来一些分享。今天的文章主要聚焦在RAG。 近期调研了一系…

Prompt工程--AI开发--可置顶粘贴小工具

PROMPT 1.背景要求:我需要开发一个简单的粘贴小工具,用于方便地粘贴和管理文本内容。该工具需要具备以下功能:粘贴功能:提供一个文本框,用户可以粘贴内容。窗口置顶:支持窗口置顶功能,确保窗口…

FPGA自学之路:到底有多崎岖?

FPGA,即现场可编程门阵列,被誉为硬件世界的“瑞士军刀”,其灵活性和可编程性让无数开发者为之倾倒。但谈及FPGA的学习难度,不少人望而却步。那么,FPGA自学之路到底有多崎岖呢? 几座大山那么高?…

它真的可以绕过 ICloud 激活吗

作为最著名的越狱辅助应用程序之一,3u工具 非常出色地将各种越狱工具和功能集成到一个应用程序中。除了越狱之外,3u工具 有时也被认为是 iCloud 激活锁绕过工具。 但3u工具真的能绕过激活锁吗? 如果没有的话还有其他的应用吗? 这…

手写顺序流程图组件

效果图 完整代码 <template><div><div class"container" :style"{ width: ${spacingX * (colNum - 1) itemWidth * colNum}px }"><divv-for"(item, i) in recordList":key"i"class"list-box":style&…