IndexedDB 数据库的使用

前端的存储方式

前端的存储,可以使得页面交互更加友好,特别是在保存草稿,网络差的情况下对用户来说是很有用的。

前端的存储方式有多种,像 Local storage、Session storage、IndexedDB、Web Sql、Cookies等这几种。
在这里插入图片描述

使用场景

我们比较常见的是本地存储,像用户的基本信息,需要在多个页面需要的时候,可以在登入的时候存储在本地,及时下次退出之后,登入信息还可以保存,这样减少了用户的输入量。
但是,它也是有缺点的,它的存储大小只有5M,只能满足相对较小的数据存储,如果是大量的数据,是不现实的,比如草稿数据。

特殊场景

在公司页面里面使用app的时候,会遇到网络情况特别差的时候,导致这些数据没法提交,如果不存储的话,下次就直接没有了,这让用户投诉了起来。于是,我只能想着本地存储了,当时想到了IndexedDB,但是之前没使用过,公司也没找到案例,搜了很多文章也发现代码写的很复杂,于是我放弃了,先使用local storage 使用试试效果,效果是很好,但是存储空间实在是没法满足,两张工单保存一些数据就满了,导致保存失败。
当时想的是保存失败的策略,全部清除或者就失败把,但是都不满足要求。
于是,必须去调研一下IndexedDB.

现成的库

当时的思路是找别人的案例,github,但是都没有一个比较简单,完整的case。后来转变了思路,我应该找下是否有成熟的库,功夫不负有心人,找到了一个库,dexie,看了一下官网以及github的star,文档非常的完善,以及star人数也达到9K。还有专门针对vue react 等不同框架的文档,于是就上手使用啦。

优点

  1. 可以存储大量的数据
  2. 没有严格的数据类型限制
  3. 异步
  4. dexie库 (index DB)

代码实现

  • 写一个公共的db.ts,用于定义数据库和表
// db.ts
import Dexie, { Table } from 'dexie';

// 表单填写存储字段
export interface FormData {
    id: string;
    scenesOne: string;
    scenesTwo: string;
    reasonClass: string;
    subReasonClass: string;
    reasonDesc: string;
    problemCell: string;
    customerFeedback: string;
    disapprovalReason: string;
    isUserOnsite: string;
    absenceReasons: string;
    additionalInfo: string;
    otherTips: string;
    otherAmount: string;
    nowTime: string;
    lng: string;
    lat: string;
    feePhotoArray: Array<any>;
    feeUrlStr: string;
    queueIploadFile: Array<any>;
}

// 方案制定存储字段
export interface PlanData {
    id: string;
    selectSolutionValue: string;
    solutionDesc: string;
    selectTimeValue: string;
}

// 一键测试存储字段

export interface TestData {
    id: any;
    itemChecked: Array<any>;
    httpTestResult: Array<any>;
    httpTestInfo: object;
    httpTestStatus: number;
    phoneTestStatus: number;
    phoneTestResult: Array<any>;
    FtpTestStatus: number;
    ftpUploadTestResult: Array<any>;
    ftpTestDownResult: Array<any>;
    coverTestTime: number;
    coverTestStatus: number;
    netWorkType: string;
    adjacentList: Array<any>;
    currentTrack: Array<any>;
    selectLocation: string;
    selectDot: string;
}

// 拍照存储数据
export interface PhotoData {
    id: string;
    nowTime: string;
    address: string;
    getSignLng: number;
    getSignLat: number;
    outerImageArray: Array<any>;
    innerImageArray: Array<any>;
    otherImageArray: Array<any>;
    queueIploadFile: Array<any>;
}

export class MySubClassedDexie extends Dexie {
    formDB!: Table<FormData>;
    PlanDB!: Table<PlanData>;
    testDB!: Table<TestData>;
    photoDB!: Table<PhotoData>;

    constructor() {
        super('myDatabase');
        this.version(1).stores({
            formDB: 'id, scenesOne, scenesTwo, reasonClass, subReasonClass, reasonDesc, problemCell, customerFeedback, disapprovalReason, isUserOnsite, absenceReasons, additionalInfo, otherTips, otherAmount, nowTime, lng, lat, feePhotoArray, feeUrlStr',
            PlanDB: 'id, selectSolutionValue, solutionDesc, selectTimeValue',
            testDB: 'id, itemChecked, httpTestResult, httpTestInfo,httpTestStatus,phoneTestStatus,phoneTestResult,FtpTestStatus,ftpUploadTestResult,ftpTestDownResult,coverTestTime,coverTestStatus,netWorkType, adjacentList,currentTrack,selectLocation,selectDot',
            photoDB: 'id,nowTime,address,getSignLng,getSignLat,outerImageArray,innerImageArray,otherImageArray,queueIploadFile'
        });
    }
}

export const db = new MySubClassedDexie();
  • 在组件中实现,用于保存在本地草稿
	private async openIDB() {
		const routerParam: any = this.$route.params;
		const id = routerParam.id || routerParam?.item['工单编号'];
		// 增加数据
		const params = {
			id: id,
			selectSolutionValue: this.selectSolutionValue,
			solutionDesc: this.solutionDesc,
			selectTimeValue: this.selectTimeValue
		};
		const cur = await db.PlanDB.get(id);
		if (cur) {
			db.PlanDB.put(params);
		} else {
			db.PlanDB.add(params);
		}

		Toast.succeed('草稿已保存');
	}
  • 当数据提交成功时,需要删除本地缓存的数据
// 清除缓存数据
				db.PlanDB.get(id).then((item: any) => {
					if (item) {
						db.PlanDB.get(id).then((result: any) => {
							if (result.id) {
								db.PlanDB.delete(id);
							}
						});
					}
				});
  • 当进入页面的时候,获取本地缓存数据,展示在页面
private getLocalData() {
		const routerParam: any = this.$route.params;
		const id = routerParam.id || routerParam?.item['工单编号'];
		db.PlanDB.get(id).then((res: any) => {
			if (res) {
				const data = res;
				this.solutionDesc = data.solutionDesc;
				this.selectSolutionValue = data.selectSolutionValue;
				this.selectTimeValue = data.selectTimeValue;
			}
		});
	}

注意:读取数据、新增数据都是异步的,promise封装好的。
项目效果:
在这里插入图片描述
参考链接:
https://dexie.org/docs/Tutorial/Vue

赶紧用起来吧。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值