vuexIndexedDBPlugin.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // import { saveData, getData } from "@/utils/indexedDb";
  2. // import { stringify, parse } from "flatted"; // 用于处理循环引用 压缩数据处理
  3. // import pako from "pako";
  4. // import { Message } from "element-ui";
  5. // // 通用分片函数
  6. // const splitIntoChunks = (data, chunkSize) => {
  7. // const chunks = [];
  8. // for (let i = 0; i < data.length; i += chunkSize) {
  9. // chunks.push(data.slice(i, i + chunkSize));
  10. // }
  11. // return chunks;
  12. // };
  13. // // 修改后的 openDB 方法
  14. // const openDB = (dbName, version) => {
  15. // return new Promise((resolve, reject) => {
  16. // const request = indexedDB.open(dbName, version);
  17. // request.onsuccess = () => {
  18. // resolve(request.result);
  19. // };
  20. // request.onerror = (error) => {
  21. // reject(error);
  22. // };
  23. // request.onupgradeneeded = (event) => {
  24. // const db = event.target.result;
  25. // // 创建对象存储(如果不存在)
  26. // if (!db.objectStoreNames.contains("dragChart_chunk_meta")) {
  27. // db.createObjectStore("dragChart_chunk_meta");
  28. // }
  29. // if (!db.objectStoreNames.contains("dragChart_compressed")) {
  30. // db.createObjectStore("dragChart_compressed");
  31. // }
  32. // if (!db.objectStoreNames.contains("myIndexedDB")) {
  33. // db.createObjectStore("myIndexedDB");
  34. // }
  35. // };
  36. // });
  37. // };
  38. // // vuex 插件
  39. // const vuexIndexedDBPlugin = (store) => {
  40. // const dbName = "vuexDB";
  41. // const keyName = "vuexState";
  42. // // 过滤 Vuex 状态,去掉不可序列化的部分
  43. // const filterState = (state) => {
  44. // const clonedState = JSON.parse(
  45. // JSON.stringify(state, (key, value) => {
  46. // // 如果是函数或无法克隆的对象,返回 undefined
  47. // if (typeof value === "function") return undefined;
  48. // return value;
  49. // })
  50. // );
  51. // return clonedState;
  52. // };
  53. // // 初始化 IndexedDB 并加载状态
  54. // openDB(dbName, 1).then(() => {
  55. // getData(dbName, keyName).then((savedState) => {
  56. // if (savedState) {
  57. // store.replaceState({
  58. // ...store.state,
  59. // ...savedState,
  60. // });
  61. // }
  62. // });
  63. // });
  64. // // 订阅 Vuex mutations,每次状态变更时保存到 IndexedDB
  65. // store.subscribe((mutation, state) => {
  66. // if (mutation.type.startsWith("dragChart/")) {
  67. // const dragChartState = state.dragChart;
  68. // try {
  69. // const cleanedState = JSON.parse(
  70. // JSON.stringify(dragChartState, (key, value) => {
  71. // if (
  72. // typeof value === "function" ||
  73. // value instanceof HTMLElement ||
  74. // value === undefined
  75. // ) {
  76. // return undefined;
  77. // }
  78. // return value;
  79. // })
  80. // );
  81. // // 压缩或分片存储
  82. // const chunkSize = 500;
  83. // if (
  84. // cleanedState.currentChartList &&
  85. // Array.isArray(cleanedState.currentChartList)
  86. // ) {
  87. // const chunks = splitIntoChunks(
  88. // cleanedState.currentChartList,
  89. // chunkSize
  90. // );
  91. // chunks.forEach((chunk, index) => {
  92. // const chunkKey = `dragChart_chunk_${index}`;
  93. // saveData("myIndexedDB", chunkKey, chunk)
  94. // .then(() => {
  95. // console.log(`Chunk ${index} saved successfully`);
  96. // })
  97. // .catch((error) =>
  98. // console.error(`Failed to save chunk ${index}:`, error)
  99. // );
  100. // });
  101. // saveData("myIndexedDB", "dragChart_chunk_meta", {
  102. // totalChunks: chunks.length,
  103. // });
  104. // }
  105. // // 存储压缩的元数据
  106. // const compressedData = pako.deflate(stringify(cleanedState), {
  107. // to: "string",
  108. // });
  109. // saveData("myIndexedDB", "dragChart_compressed", compressedData)
  110. // .then(() => {
  111. // //console.log("Compressed metadata saved")
  112. // })
  113. // .catch((error) =>
  114. // console.error("Failed to save compressed metadata:", error)
  115. // );
  116. // } catch (error) {
  117. // console.error("Error processing dragChart state:", error);
  118. // Message({
  119. // message: "数据存储已满,请刷新页面进行数据清除" + error,
  120. // type: "error",
  121. // });
  122. // }
  123. // }
  124. // });
  125. // };
  126. // export default vuexIndexedDBPlugin;
  127. import { saveData, getData } from "@/utils/indexedDb";
  128. import { Message } from "element-ui";
  129. // 通用的过滤 Vuex 状态,去掉不可序列化的部分
  130. const filterState = (state) => {
  131. const clonedState = JSON.parse(
  132. JSON.stringify(state, (key, value) => {
  133. // 如果是函数或无法克隆的对象,返回 undefined
  134. if (
  135. typeof value === "function" ||
  136. value instanceof HTMLElement ||
  137. value === undefined
  138. ) {
  139. return undefined;
  140. }
  141. return value;
  142. })
  143. );
  144. return clonedState;
  145. };
  146. // // 修改后的 openDB 方法
  147. // const openDB = (dbName, version) => {
  148. // return new Promise((resolve, reject) => {
  149. // const request = indexedDB.open(dbName, version);
  150. // request.onsuccess = () => {
  151. // resolve(request.result);
  152. // };
  153. // request.onerror = (error) => {
  154. // reject(error);
  155. // };
  156. // request.onupgradeneeded = (event) => {
  157. // const db = event.target.result;
  158. // // 创建对象存储(如果不存在)
  159. // if (!db.objectStoreNames.contains("myIndexedDB")) {
  160. // db.createObjectStore("myIndexedDB");
  161. // }
  162. // };
  163. // });
  164. // };
  165. const openDB = (dbName, version) => {
  166. return new Promise((resolve, reject) => {
  167. const request = indexedDB.open(dbName, version);
  168. request.onsuccess = () => {
  169. resolve(request.result);
  170. };
  171. request.onerror = (error) => {
  172. reject(error);
  173. };
  174. request.onupgradeneeded = (event) => {
  175. const db = event.target.result;
  176. // 创建对象存储,确保名称为 vuexData(与getData中的名称一致)
  177. if (!db.objectStoreNames.contains("vuexData")) {
  178. db.createObjectStore("vuexData");
  179. }
  180. };
  181. });
  182. };
  183. // vuex 插件
  184. const vuexIndexedDBPlugin = (store) => {
  185. const dbName = "vuexDB";
  186. const keyName = "vuexState";
  187. // 初始化 IndexedDB 并加载状态
  188. openDB(dbName, 1).then(() => {
  189. getData(dbName, keyName).then((savedState) => {
  190. if (savedState) {
  191. store.replaceState({
  192. ...store.state,
  193. ...savedState,
  194. });
  195. }
  196. });
  197. });
  198. // 订阅 Vuex mutations,每次状态变更时保存到 IndexedDB
  199. store.subscribe((mutation, state) => {
  200. if (mutation.type.startsWith("dragChart/")) {
  201. const dragChartState = state.dragChart;
  202. try {
  203. // 过滤不需要保存的内容
  204. const cleanedState = filterState(dragChartState);
  205. // 直接保存整个状态到 IndexedDB
  206. saveData("vuexData", keyName, cleanedState)
  207. .then(() => {
  208. console.log("State saved successfully");
  209. })
  210. .catch((error) => {
  211. console.error("Failed to save state:", error);
  212. Message({
  213. message: "数据存储失败:" + error,
  214. type: "error",
  215. });
  216. });
  217. } catch (error) {
  218. console.error("Error processing dragChart state:", error);
  219. Message({
  220. message: "数据存储失败,请刷新页面进行数据清除:" + error,
  221. type: "error",
  222. });
  223. }
  224. }
  225. });
  226. };
  227. export default vuexIndexedDBPlugin;