flat: 缓存

This commit is contained in:
Apcallover
2025-11-28 19:47:42 +08:00
parent 550173c82d
commit d84fd90a11
10 changed files with 691 additions and 12 deletions

View File

@@ -1,8 +1,12 @@
import App from '@/App' import App from '@/App'
import * as Pinia from 'pinia' import * as Pinia from 'pinia'
import {
createUnistorage
} from "./uni_modules/pinia-plugin-unistorage";
import globalFunction from '@/common/globalFunction' import globalFunction from '@/common/globalFunction'
import '@/lib/string-similarity.min.js' import '@/lib/string-similarity.min.js'
import similarityJobs from '@/utils/similarity_Job.js'; import similarityJobs from '@/utils/similarity_Job.js';
// 组件 // 组件
import AppLayout from './components/AppLayout/AppLayout.vue'; import AppLayout from './components/AppLayout/AppLayout.vue';
import Empty from './components/empty/empty.vue'; import Empty from './components/empty/empty.vue';
@@ -65,7 +69,10 @@ export function createApp() {
app.provide('deviceInfo', globalFunction.getdeviceInfo()); app.provide('deviceInfo', globalFunction.getdeviceInfo());
app.use(SelectPopupPlugin); app.use(SelectPopupPlugin);
app.use(Pinia.createPinia());
const store = Pinia.createPinia();
store.use(createUnistorage());
app.use(store);
return { return {
app, app,

View File

@@ -110,13 +110,13 @@ import FileUploader from '@/utils/FileUploader.js';
const { $api, navTo } = inject('globalFunction'); const { $api, navTo } = inject('globalFunction');
import useUserStore from '@/stores/useUserStore'; import useUserStore from '@/stores/useUserStore';
const popup = ref(null); const popup = ref(null);
const { userInfo, Completion } = storeToRefs(useUserStore()); const { userInfo, Completion, counts } = storeToRefs(useUserStore());
const counts = ref({});
function logOut() { function logOut() {
popup.value.open(); popup.value.open();
} }
onShow(() => { onShow(() => {
getUserstatistics(); useUserStore().getUserstatistics();
}); });
function close() { function close() {
@@ -129,12 +129,6 @@ function confirm() {
const isAbove90 = (percent) => parseFloat(percent) < 90; const isAbove90 = (percent) => parseFloat(percent) < 90;
function getUserstatistics() {
$api.createRequest('/app/user/statistics').then((resData) => {
counts.value = resData.data;
});
}
function selectFile() { function selectFile() {
// FileUploader.showMenuAndUpload({ // FileUploader.showMenuAndUpload({
// success: function (res) { // success: function (res) {

View File

@@ -108,4 +108,6 @@ export const useReadMsg = defineStore('readMsg', () => {
markAsRead, markAsRead,
updateTabBarBadge updateTabBarBadge
} }
}, {
unistorage: true,
}) })

View File

@@ -14,6 +14,10 @@ import {
import { import {
useReadMsg useReadMsg
} from '@/stores/useReadMsg'; } from '@/stores/useReadMsg';
import {
msg,
$api,
} from '../common/globalFunction';
// 简历完成度计算 // 简历完成度计算
function getResumeCompletionPercentage(resume) { function getResumeCompletionPercentage(resume) {
@@ -52,7 +56,8 @@ const useUserStore = defineStore("user", () => {
const token = ref('') const token = ref('')
const resume = ref({}) const resume = ref({})
const Completion = ref('0%') const Completion = ref('0%')
const seesionId = ref(uni.getStorageSync('seesionId') || '') const seesionId = ref('')
const counts = ref({})
const login = (value) => { const login = (value) => {
hasLogin.value = true; hasLogin.value = true;
@@ -128,6 +133,13 @@ const useUserStore = defineStore("user", () => {
seesionId.value = seesionIdVal seesionId.value = seesionIdVal
} }
function getUserstatistics() {
$api.createRequest('/app/user/statistics').then((resData) => {
counts.value = resData.data;
});
}
// 导入 // 导入
return { return {
hasLogin, hasLogin,
@@ -140,8 +152,12 @@ const useUserStore = defineStore("user", () => {
getUserResume, getUserResume,
initSeesionId, initSeesionId,
seesionId, seesionId,
Completion Completion,
getUserstatistics,
counts
} }
}, {
unistorage: true,
}) })
export default useUserStore; export default useUserStore;

View File

@@ -0,0 +1,31 @@
## 0.1.22024-07-17
chore: 移除冗余的 typescript 依赖
## 0.1.12024-07-17
fix: 修复 createUnistorage 导出
## 0.1.02024-07-10
fix!: 更新 pinia 类型
## 0.0.212024-07-10
chore!: 继承 pinia-plugin-persistedstate
## 0.0.192024-01-18
fix: 重新构建,不需要默认参数
## 0.0.162023-05-06
fix: 修复全局 key 移除
## 0.0.142023-04-29
fix: 修复全局 global key 选项
## 0.0.122023-04-07
- fix: 修复类型错误
## 0.0.112023-03-22
- chore: ts 支持
## 0.0.72022-04-29
- 更新 README

View File

@@ -0,0 +1,112 @@
import * as pinia from 'pinia';
import { StateTree, PiniaPluginContext, PiniaPlugin } from 'pinia';
type Prettify<T> = {
[K in keyof T]: T[K];
};
type StorageLike = Pick<Storage, 'getItem' | 'setItem'>;
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<string>;
/**
* 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<Pick<PersistedStateOptions, 'storage' | 'serializer' | 'afterRestore' | 'beforeRestore' | 'debug'> & {
/**
* 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<S extends StateTree, Store> {
/**
* 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;

View File

@@ -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 };

View File

@@ -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"
}
}
}
}
}

View File

@@ -0,0 +1,226 @@
<div align="center">
<img width="200px" height="200px" src="https://gitee.com/dishait/pinia-plugin-unistorage/raw/main/static/favicon.png" />
<h1>pinia-plugin-unistorage</h1>
<p>uniapp 下 pinia 的本地数据缓存插件</p>
</div>
<br />
<br />
<div align="center">
<img width="100%" height="100%" src="https://gitee.com/dishait/pinia-plugin-unistorage/raw/main/static/pinia-plugin-unistorage.gif" />
</div>
<br />
<br />
## 引用
该插件是
[pinia-plugin-persistedstate](https://github.com/prazdevs/pinia-plugin-persistedstate)
`uniapp` 版本,如果你需要在纯 `vue` 或者 `nuxt` 项目中使用 `pinia`
的本地数据缓存,请使用
[pinia-plugin-persistedstate](https://github.com/prazdevs/pinia-plugin-persistedstate)。
<br />
<br />
## 动机
为了实现多端的更简单的全局本地数据缓存
<br />
<br />
## 组织 🦔
欢迎关注 **帝莎编程**
- [官网](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)
<br />
<br />
## 使用
### 安装
#### 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 返回
};
}
```
<br />
#### 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 的数据读写都将持久化
},
);
```
<br />
### 选项
#### 钩子
```js
import { defineStore } from "pinia";
export const useStore = defineStore("main", {
state() {
return {
someState: "hello pinia",
};
},
unistorage: {
// 初始化恢复前触发
beforeRestore(ctx) {},
// 初始化恢复后触发
afterRestore(ctx) {},
},
});
```
<br />
#### 序列化
大多数情况下你并不需要了解该选项
```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);
},
},
},
});
```
<br />
#### 其他
```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 会被缓存
},
});
```
<br />
<br />
## License
Made with [markthree](https://github.com/markthree)
Published under [MIT License](./LICENSE).

View File

@@ -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);
};
}