diff --git a/main.js b/main.js index 671b533..2ebf500 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,12 @@ import App from '@/App' import * as Pinia from 'pinia' +import { + createUnistorage +} from "./uni_modules/pinia-plugin-unistorage"; import globalFunction from '@/common/globalFunction' import '@/lib/string-similarity.min.js' import similarityJobs from '@/utils/similarity_Job.js'; + // 组件 import AppLayout from './components/AppLayout/AppLayout.vue'; import Empty from './components/empty/empty.vue'; @@ -65,7 +69,10 @@ export function createApp() { app.provide('deviceInfo', globalFunction.getdeviceInfo()); app.use(SelectPopupPlugin); - app.use(Pinia.createPinia()); + + const store = Pinia.createPinia(); + store.use(createUnistorage()); + app.use(store); return { app, diff --git a/pages/mine/mine.vue b/pages/mine/mine.vue index 71f5645..afbcc5f 100644 --- a/pages/mine/mine.vue +++ b/pages/mine/mine.vue @@ -110,13 +110,13 @@ import FileUploader from '@/utils/FileUploader.js'; const { $api, navTo } = inject('globalFunction'); import useUserStore from '@/stores/useUserStore'; const popup = ref(null); -const { userInfo, Completion } = storeToRefs(useUserStore()); -const counts = ref({}); +const { userInfo, Completion, counts } = storeToRefs(useUserStore()); + function logOut() { popup.value.open(); } onShow(() => { - getUserstatistics(); + useUserStore().getUserstatistics(); }); function close() { @@ -129,12 +129,6 @@ function confirm() { const isAbove90 = (percent) => parseFloat(percent) < 90; -function getUserstatistics() { - $api.createRequest('/app/user/statistics').then((resData) => { - counts.value = resData.data; - }); -} - function selectFile() { // FileUploader.showMenuAndUpload({ // success: function (res) { diff --git a/stores/useReadMsg.js b/stores/useReadMsg.js index 5e78e60..7f0760d 100644 --- a/stores/useReadMsg.js +++ b/stores/useReadMsg.js @@ -108,4 +108,6 @@ export const useReadMsg = defineStore('readMsg', () => { markAsRead, updateTabBarBadge } +}, { + unistorage: true, }) \ No newline at end of file diff --git a/stores/useUserStore.js b/stores/useUserStore.js index e489188..cd1e655 100644 --- a/stores/useUserStore.js +++ b/stores/useUserStore.js @@ -14,6 +14,10 @@ import { import { useReadMsg } from '@/stores/useReadMsg'; +import { + msg, + $api, +} from '../common/globalFunction'; // 简历完成度计算 function getResumeCompletionPercentage(resume) { @@ -52,7 +56,8 @@ const useUserStore = defineStore("user", () => { const token = ref('') const resume = ref({}) const Completion = ref('0%') - const seesionId = ref(uni.getStorageSync('seesionId') || '') + const seesionId = ref('') + const counts = ref({}) const login = (value) => { hasLogin.value = true; @@ -128,6 +133,13 @@ const useUserStore = defineStore("user", () => { seesionId.value = seesionIdVal } + function getUserstatistics() { + $api.createRequest('/app/user/statistics').then((resData) => { + counts.value = resData.data; + }); + } + + // 导入 return { hasLogin, @@ -140,8 +152,12 @@ const useUserStore = defineStore("user", () => { getUserResume, initSeesionId, seesionId, - Completion + Completion, + getUserstatistics, + counts } +}, { + unistorage: true, }) export default useUserStore; \ No newline at end of file diff --git a/uni_modules/pinia-plugin-unistorage/changelog.md b/uni_modules/pinia-plugin-unistorage/changelog.md new file mode 100644 index 0000000..053621c --- /dev/null +++ b/uni_modules/pinia-plugin-unistorage/changelog.md @@ -0,0 +1,31 @@ +## 0.1.2(2024-07-17) +chore: 移除冗余的 typescript 依赖 +## 0.1.1(2024-07-17) +fix: 修复 createUnistorage 导出 +## 0.1.0(2024-07-10) +fix!: 更新 pinia 类型 +## 0.0.21(2024-07-10) +chore!: 继承 pinia-plugin-persistedstate +## 0.0.19(2024-01-18) + +fix: 重新构建,不需要默认参数 + +## 0.0.16(2023-05-06) + +fix: 修复全局 key 移除 + +## 0.0.14(2023-04-29) + +fix: 修复全局 global key 选项 + +## 0.0.12(2023-04-07) + +- fix: 修复类型错误 + +## 0.0.11(2023-03-22) + +- chore: ts 支持 + +## 0.0.7(2022-04-29) + +- 更新 README diff --git a/uni_modules/pinia-plugin-unistorage/index.d.ts b/uni_modules/pinia-plugin-unistorage/index.d.ts new file mode 100644 index 0000000..b6d3c73 --- /dev/null +++ b/uni_modules/pinia-plugin-unistorage/index.d.ts @@ -0,0 +1,112 @@ +import * as pinia from 'pinia'; +import { StateTree, PiniaPluginContext, PiniaPlugin } from 'pinia'; + +type Prettify = { + [K in keyof T]: T[K]; +}; +type StorageLike = Pick; +interface Serializer { + /** + * Serializes state into string before storing + * @default JSON.stringify + */ + serialize: (value: StateTree) => string; + /** + * Deserializes string into state before hydrating + * @default JSON.parse + */ + deserialize: (value: string) => StateTree; +} +interface PersistedStateOptions { + /** + * Storage key to use. + * @default $store.id + */ + key?: string | ((id: string) => string); + /** + * Where to store persisted state. + * @default localStorage + */ + storage?: StorageLike; + /** + * Dot-notation paths to partially save state. Saves everything if undefined. + * @default undefined + */ + paths?: Array; + /** + * Customer serializer to serialize/deserialize state. + */ + serializer?: Serializer; + /** + * Hook called before state is hydrated from storage. + * @default null + */ + beforeRestore?: (context: PiniaPluginContext) => void; + /** + * Hook called after state is hydrated from storage. + * @default undefined + */ + afterRestore?: (context: PiniaPluginContext) => void; + /** + * Logs errors in console when enabled. + * @default false + */ + debug?: boolean; +} +type PersistedStateFactoryOptions = Prettify & { + /** + * Global key generator, allows pre/postfixing store keys. + * @default storeKey => storeKey + */ + key?: (storeKey: string) => string; + /** + * Automatically persists all stores, opt-out individually. + * @default false + */ + auto?: boolean; +}>; +declare module 'pinia' { + interface DefineStoreOptionsBase { + /** + * Persists store in storage. + * @see https://prazdevs.github.io/pinia-plugin-persistedstate + */ + persist?: boolean | PersistedStateOptions | PersistedStateOptions[]; + unistorage?: boolean | PersistedStateOptions | PersistedStateOptions[]; + } + interface PiniaCustomProperties { + /** + * Rehydrates store from persisted state + * Warning: this is for advances usecases, make sure you know what you're doing. + * @see https://prazdevs.github.io/pinia-plugin-persistedstate/guide/advanced.html#forcing-the-rehydration + */ + $hydrate: (opts?: { + runHooks?: boolean; + }) => void; + /** + * Persists store into configured storage + * Warning: this is for advances usecases, make sure you know what you're doing. + * @see https://prazdevs.github.io/pinia-plugin-persistedstate/guide/advanced.html#forcing-the-persistence + */ + $persist: () => void; + } +} + +/** + * Creates a pinia persistence plugin + * @param factoryOptions global persistence options + * @returns pinia plugin + */ +declare function createPersistedState(factoryOptions?: PersistedStateFactoryOptions): PiniaPlugin; + +declare const _default: pinia.PiniaPlugin; + +export { PersistedStateFactoryOptions, PersistedStateOptions, Serializer, StorageLike, createPersistedState, _default as default, createUnistorage }; + +/** + * Creates a pinia persistence plugin with uniapp + * @param factoryOptions global persistence options + * @returns pinia plugin + */ +declare function createUnistorage(factoryOptions?: PersistedStateFactoryOptions): PiniaPlugin; + \ No newline at end of file diff --git a/uni_modules/pinia-plugin-unistorage/index.js b/uni_modules/pinia-plugin-unistorage/index.js new file mode 100644 index 0000000..02c4e79 --- /dev/null +++ b/uni_modules/pinia-plugin-unistorage/index.js @@ -0,0 +1,162 @@ +// src/normalize.ts +function isObject(v) { + return typeof v === "object" && v !== null; +} +function normalizeOptions(options, factoryOptions) { + options = isObject(options) ? options : /* @__PURE__ */ Object.create(null); + return new Proxy(options, { + get(target, key, receiver) { + if (key === "key") + return Reflect.get(target, key, receiver); + return Reflect.get(target, key, receiver) || Reflect.get(factoryOptions, key, receiver); + } + }); +} + +// src/pick.ts +function get(state, path) { + return path.reduce((obj, p) => { + return obj == null ? void 0 : obj[p]; + }, state); +} +function set(state, path, val) { + return path.slice(0, -1).reduce((obj, p) => { + if (/^(__proto__)$/.test(p)) + return {}; + else + return obj[p] = obj[p] || {}; + }, state)[path[path.length - 1]] = val, state; +} +function pick(baseState, paths) { + return paths.reduce((substate, path) => { + const pathArray = path.split("."); + return set(substate, pathArray, get(baseState, pathArray)); + }, {}); +} + +// src/plugin.ts +function parsePersistence(factoryOptions, store) { + return (o) => { + var _a; + try { + const { + storage = localStorage, + beforeRestore = void 0, + afterRestore = void 0, + serializer = { + serialize: JSON.stringify, + deserialize: JSON.parse + }, + key = store.$id, + paths = null, + debug = false + } = o; + return { + storage, + beforeRestore, + afterRestore, + serializer, + key: ((_a = factoryOptions.key) != null ? _a : (k) => k)(typeof key == "string" ? key : key(store.$id)), + paths, + debug + }; + } catch (e) { + if (o.debug) + console.error("[pinia-plugin-persistedstate]", e); + return null; + } + }; +} +function hydrateStore(store, { storage, serializer, key, debug }) { + try { + const fromStorage = storage == null ? void 0 : storage.getItem(key); + if (fromStorage) + store.$patch(serializer == null ? void 0 : serializer.deserialize(fromStorage)); + } catch (e) { + if (debug) + console.error("[pinia-plugin-persistedstate]", e); + } +} +function persistState(state, { storage, serializer, key, paths, debug }) { + try { + const toStore = Array.isArray(paths) ? pick(state, paths) : state; + storage.setItem(key, serializer.serialize(toStore)); + } catch (e) { + if (debug) + console.error("[pinia-plugin-persistedstate]", e); + } +} +function createPersistedState(factoryOptions = {}) { + return (context) => { + const { auto = false } = factoryOptions; + const { + options: { persist = auto }, + store, + pinia + } = context; + if (!persist) + return; + if (!(store.$id in pinia.state.value)) { + const original_store = pinia._s.get(store.$id.replace("__hot:", "")); + if (original_store) + Promise.resolve().then(() => original_store.$persist()); + return; + } + const persistences = (Array.isArray(persist) ? persist.map((p) => normalizeOptions(p, factoryOptions)) : [normalizeOptions(persist, factoryOptions)]).map(parsePersistence(factoryOptions, store)).filter(Boolean); + store.$persist = () => { + persistences.forEach((persistence) => { + persistState(store.$state, persistence); + }); + }; + store.$hydrate = ({ runHooks = true } = {}) => { + persistences.forEach((persistence) => { + const { beforeRestore, afterRestore } = persistence; + if (runHooks) + beforeRestore == null ? void 0 : beforeRestore(context); + hydrateStore(store, persistence); + if (runHooks) + afterRestore == null ? void 0 : afterRestore(context); + }); + }; + persistences.forEach((persistence) => { + const { beforeRestore, afterRestore } = persistence; + beforeRestore == null ? void 0 : beforeRestore(context); + hydrateStore(store, persistence); + afterRestore == null ? void 0 : afterRestore(context); + store.$subscribe( + (_mutation, state) => { + persistState(state, persistence); + }, + { + detached: true + } + ); + }); + }; +} + +function createUnistorage(globalOptions = {}) { + const persistedState = createPersistedState({ + storage: { + getItem(key) { + return uni.getStorageSync(key); + }, + setItem(key, value) { + uni.setStorageSync(key, value); + } + }, + serializer: { + deserialize: JSON.parse, + serialize: JSON.stringify + }, + ...globalOptions + }); + return (ctx) => { + if (ctx.options.unistorage) { + ctx.options.persist = ctx.options.unistorage; + } + return persistedState(ctx); + }; +} + +export { createPersistedState, createUnistorage }; diff --git a/uni_modules/pinia-plugin-unistorage/package.json b/uni_modules/pinia-plugin-unistorage/package.json new file mode 100644 index 0000000..fd82db4 --- /dev/null +++ b/uni_modules/pinia-plugin-unistorage/package.json @@ -0,0 +1,94 @@ +{ + "id": "pinia-plugin-unistorage", + "displayName": "pinia-plugin-unistorage", + "version": "0.1.2", + "description": "uniapp 下 pinia 的本地数据缓存插件", + "keywords": [ + "pinia", + "uniapp", + "storage", + "pinia-plugin", + "persistence" +], + "type": "module", + "main": "./index.js", + "types": "./index.d.ts", + "exports": { + ".": { + "import": "./index.js", + "types": "./index.d.ts" + } + }, + "engines": { + "HBuilderX": "^3.4.7" + }, + "dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/pinia-plugin-unistorage", + "type": "sdk-js" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y", + "alipay": "n" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "y", + "快手": "y", + "飞书": "y", + "京东": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + } + } + } + } +} diff --git a/uni_modules/pinia-plugin-unistorage/readme.md b/uni_modules/pinia-plugin-unistorage/readme.md new file mode 100644 index 0000000..7724e13 --- /dev/null +++ b/uni_modules/pinia-plugin-unistorage/readme.md @@ -0,0 +1,226 @@ +
+ +

pinia-plugin-unistorage

+

uniapp 下 pinia 的本地数据缓存插件

+
+ +
+
+ +
+ +
+ +
+
+ +## 引用 + +该插件是 +[pinia-plugin-persistedstate](https://github.com/prazdevs/pinia-plugin-persistedstate) +的 `uniapp` 版本,如果你需要在纯 `vue` 或者 `nuxt` 项目中使用 `pinia` +的本地数据缓存,请使用 +[pinia-plugin-persistedstate](https://github.com/prazdevs/pinia-plugin-persistedstate)。 + +
+
+ +## 动机 + +为了实现多端的更简单的全局本地数据缓存 + +
+
+ +## 组织 🦔 + +欢迎关注 **帝莎编程** + +- [官网](http://dishaxy.dishait.cn/) +- [Gitee](https://gitee.com/dishait) +- [Github](https://github.com/dishait) +- [网易云课堂](https://study.163.com/provider/480000001892585/index.htm?share=2&shareId=480000001892585) + +
+
+ +## 使用 + +### 安装 + +#### 1. `cli` 创建的 `uniapp` 项目 + +```shell +npm i pinia-plugin-unistorage -D +``` + +```js +// main.js +import { createSSRApp } from "vue"; +import * as Pinia from "pinia"; +import { createUnistorage } from "pinia-plugin-unistorage"; + +export function createApp() { + const app = createSSRApp(App); + + const store = Pinia.createPinia(); + + // 关键代码 👇 + store.use(createUnistorage()); + + app.use(store); + + return { + app, + Pinia, // 此处必须将 Pinia 返回 + }; +} +``` + +
+ +#### 2. `hbuilderx` 创建的 `uniapp` 项目 + +直接插件市场安装后引入注册 + +```js +// main.js +import { createSSRApp } from "vue"; +import * as Pinia from "pinia"; +import { createUnistorage } from "./uni_modules/pinia-plugin-unistorage"; + +export function createApp() { + const app = createSSRApp(App); + + const store = Pinia.createPinia(); + + // 关键代码 👇 + store.use(createUnistorage()); + + app.use(store); + + return { + app, + Pinia, // 此处必须将 Pinia 返回 + }; +} +``` + +### 基础 + +```js +import { defineStore } from "pinia"; + +export const useStore = defineStore("main", { + state() { + return { + someState: "hello pinia", + }; + }, + unistorage: true, // 开启后对 state 的数据读写都将持久化 +}); +``` + +或者 `setup` 语法也是支持的 + +```js +import { defineStore } from "pinia"; + +export const useStore = defineStore( + "main", + () => { + const someState = ref("hello pinia"); + return { someState }; + }, + { + unistorage: true, // 开启后对 state 的数据读写都将持久化 + }, +); +``` + +
+ +### 选项 + +#### 钩子 + +```js +import { defineStore } from "pinia"; + +export const useStore = defineStore("main", { + state() { + return { + someState: "hello pinia", + }; + }, + unistorage: { + // 初始化恢复前触发 + beforeRestore(ctx) {}, + // 初始化恢复后触发 + afterRestore(ctx) {}, + }, +}); +``` + +
+ +#### 序列化 + +大多数情况下你并不需要了解该选项 + +```js +import { defineStore } from "pinia"; + +export const useStore = defineStore("main", { + state() { + return { + someState: "hello pinia", + }; + }, + unistorage: { + serializer: { + // 序列化,默认为 JSON.stringify + serialize(v) { + return JSON.stringify(v); + }, + // 反序列化,默认为 JSON.parse + deserialize(v) { + return JSON.parse(v); + }, + }, + }, +}); +``` + +
+ +#### 其他 + +```js +import { defineStore } from "pinia"; + +export const useStore = defineStore("main", { + state() { + return { + foo: "foo", + nested: { + data: "nested pinia", + }, + someState: "hello pinia", + }; + }, + unistorage: { + key: "foo", // 缓存的键,默认为该 store 的 id,这里是 main, + paths: ["foo", "nested.data"], // 需要缓存的路径,这里设置 foo 和 nested 下的 data 会被缓存 + }, +}); +``` + +
+
+ +## License + +Made with [markthree](https://github.com/markthree) + +Published under [MIT License](./LICENSE). diff --git a/uni_modules/pinia-plugin-unistorage/src/index.ts b/uni_modules/pinia-plugin-unistorage/src/index.ts new file mode 100644 index 0000000..bc6bcb9 --- /dev/null +++ b/uni_modules/pinia-plugin-unistorage/src/index.ts @@ -0,0 +1,35 @@ +import { + createPersistedState, + type PersistedStateFactoryOptions, +} from "pinia-plugin-persistedstate"; + +export * from "pinia-plugin-persistedstate"; + +export function createUnistorage( + globalOptions: PersistedStateFactoryOptions = {}, +) { + const persistedState = createPersistedState({ + storage: { + getItem(key) { + // @ts-ignore + return uni.getStorageSync(key); + }, + setItem(key, value) { + // @ts-ignore + uni.setStorageSync(key, value); + }, + }, + serializer: { + deserialize: JSON.parse, + serialize: JSON.stringify, + }, + ...globalOptions, + }); + // @ts-ignore + return (ctx) => { + if (ctx.options.unistorage) { + ctx.options.persist = ctx.options.unistorage; + } + return persistedState(ctx); + }; +}