记录学习使用indexedDB

项目中的一些需求条件与出现的bug情况:
    1、在一个查询页中,选择列表中的一项点击预订按钮跳转到预订页(此处列表项没有id值,预定页的tagView标题要自定义内容展示,所以我是用(自定义内容拼接随机数)作为唯一标识,通过query传参 ,可以创建多个不同的预订页面进行相应操作),预定页面的渲染数据是通过查询页的路由state传参,跳转后的页面是使用history.state.data来接收传递过来的数据做渲染
    2、问题复现:在当前订单页点击标签页的刷新功能(刷新页面),会出现新创建的一个订单页,并且原来的订单页的数据会消失(大致猜测是页面刷新,路由传递的参数没传递正确,导致刷新后,没有query参数,就会创建一个新的独立的页面出来)

 

 

知道大致问题原因后,先去看了一下标签页的刷新函数

//原标签页的刷新功能

function refreshSelectedTag(view: TagView) {
  tagsViewStore.delCachedView(view);
  const { fullPath } = view;
  console.log(fullPath, "fullPath");
  nextTick(() => {
    router.replace({ path: "/redirect" + fullPath});
  });
}

//代码更改后:

function refreshSelectedTag(view: TagView) {
  tagsViewStore.delCachedView(view);
  const { fullPath } = view;
  console.log(fullPath, "fullPath");
  nextTick(() => {
    const currentRoute = router.currentRoute.value;
    const { path, query } = currentRoute;  
 // 尝试在刷新订单页的逻辑中,将之前的路由参数重新传递给新的订单页,以确保新建的订单页能够正确显示之 
 // 前的订单信息,(自我觉得:只要tag标签的内容一样就不会产生新的订单页了)
    router.replace({ path: "/redirect" + fullPath, query });
  });
}  

 新创订单页的bug解决了,但是刷新后,参数消失还没有解决。此时有个思路就是把数据存储到前端数据库中,若是刷新页面后没有数据,就从数据库中通过主键keyPath:id查询出来并渲染。id我用的是跳转时的query参数(就算页面刷新,参数也不会消失),确保id要与query参数一致,以下是我使用indexedDB的代码

==========================查询页 跳转===========================
import { openDB } from "@/utils";
import { useRouter } from "vue-router";

const router = useRouter();

//跳转预定页
const toBooking = async (item: any, index: number) => {
  if (radioValue.value.name === "") {
    return ElMessage.info("请先选择舱位");
  } else if (index !== radioValue.value.index1) {
    return ElMessage.info("请先选择价格后在预定");
  }
  const data = {
    ...item,
    price: radioValue.value,
    cabin_type: cabin_type.value,
    work_no: work_no.value,
  };
     //  tagTitle  唯一标识
  const tagTitle = `${dayjs.unix(item.fly_day).format("YYYY-MM-DD")}  ${
    item.voyage
  } ${item.flight} ${Math.floor(Math.random() * 10000)}` as string;
    //  存数据库的对象
  const obj = {
    id: tagTitle,
    info: JSON.stringify(data),
    status: false,
  };
  //添加数据到库中
  addTask(obj);

  router.push({
    name: "BookingEdit",
    query: {
      title: tagTitle,
    },
    state: { data: JSON.stringify(data) },   //使用state传参,可以传对象(不会显示到url上)
  });
};

let dbName = "order"; //定义数据库名
let version = 1;      //版本号
let db: any;          //数据库对象
//添加数据
function addTask(data: any) {
  let request = db
    .transaction("Today_Mission", "readwrite")
    .objectStore("Today_Mission")
    .add(data);
  request.onsuccess = (event: any) => {
    console.log("添加数据库成功");
  };
  request.onerror = (event: any) => {
    console.log("添加数据库失败");
  };
}
//缓存组件的两个钩子函数

onDeactivated(() => {
  clearInterval(timeId);
});

onActivated(async () => {
  db = await openDB(dbName, version);   //打开数据库
});
===================================查询页============================================


==================================utils文件封装打开数据库的方法========================

//创建数据库
export const openDB = (dbName: any, version = 1) => {
  return new Promise((resolve, reject) => {
    //兼容浏览器
    var indexedDB = window.indexedDB;
    let db;
    //打开数据库,若没有就会创建
    const request = indexedDB.open(dbName, version);
    //数据库打开成功回调
    request.onsuccess = function (event: any) {
      db = event.target.result; //数据库对象
      console.log("数据库打开成功", db);
      resolve(db);
    };
    //数据库打开失败的回调
    request.onerror = function (event) {
      console.log("数据库打开报错");
    };
    //数据库有更新时候的回调
    request.onupgradeneeded = function (event: any) {
      console.log("数据库更新");
      db = event.target.result; //数据库对象
      var objectStore;
      //创建存储库
      objectStore = db.createObjectStore("Today_Mission", { keyPath: "id" });
      // 建立索引,info可能重复,因此unique设置为false
      objectStore.createIndex("info", "info", { unique: false });
    };
  });
};
=======================================utils文件======================================

=====================================预定页 接收参数===================================
import { openDB } from "@/utils";
import { useRoute } from "vue-router";

let db: any;
let dbName = "order";
let storeName = "Today_Mission";
let version = 1;

//读取数据库数据函数  此函数会返回一个结果resolve()

function getDataByKey(db: any, storeName: string, key: string) {
  return new Promise((resolve, reject) => {
    var transaction = db.transaction([storeName]); // 事务
    var objectStore = transaction.objectStore(storeName); // 仓库对象
    var request = objectStore.get(key); // 通过主键获取数据

    request.onerror = function (event: any) {
      console.log("事务失败");
    };

    request.onsuccess = function (event: any) {
      console.log("主键查询结果: ", request.result);
      resolve(request.result);
    };
  });
}

//组件是被缓存了,所以用onActivated

onActivated(async () => {
  db = await openDB(dbName, version);
  console.log(route.query.title, "route");
  if (history.state.data) {
      ...同理处理数据
  } else {
    //刷新页面的话,就从数据库里找到这项数据渲染
    const data = (await getDataByKey(
      db,
      storeName,
      route.query.title as any
    )) as any;
    info.value = JSON.parse(data.Task);
    AmountInfoRef.value.setData(info.value);
    AmountInfoRef.value.form.seat_type = info.value.cabin_type;
    flightRef.value.setInfo(info.value);
  }
});

=======================================预定页========================================

最后一步,清空数据库数据
=======================================登录页========================================


//清空数据库操作
function clearDatabase() {
  const request = indexedDB.open("order", 1);
  request.onsuccess = function (event: any) {
    const db = event.target.result;
    const transaction = db.transaction("Today_Mission", "readwrite");
    const objectStore = transaction.objectStore("Today_Mission");
    const clearRequest = objectStore.clear();
    clearRequest.onsuccess = function () {
      console.log("数据库清空成功");
    };
    clearRequest.onerror = function (event: any) {
      console.error("数据库清空失败", event.target.error);
    };
  };
}

//登录成功就清空一遍数据库数据(防止数据过多,发生一些冲突或并发问题


=====================================================================================

以上代码能解决我目前发生的问题,在此记录一下。若代码有什么问题,欢迎指出来,改正。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值