flat: 缓存
This commit is contained in:
31
uni_modules/pinia-plugin-unistorage/changelog.md
Normal file
31
uni_modules/pinia-plugin-unistorage/changelog.md
Normal file
@@ -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
|
||||
112
uni_modules/pinia-plugin-unistorage/index.d.ts
vendored
Normal file
112
uni_modules/pinia-plugin-unistorage/index.d.ts
vendored
Normal 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;
|
||||
|
||||
162
uni_modules/pinia-plugin-unistorage/index.js
Normal file
162
uni_modules/pinia-plugin-unistorage/index.js
Normal 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 };
|
||||
94
uni_modules/pinia-plugin-unistorage/package.json
Normal file
94
uni_modules/pinia-plugin-unistorage/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
226
uni_modules/pinia-plugin-unistorage/readme.md
Normal file
226
uni_modules/pinia-plugin-unistorage/readme.md
Normal 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).
|
||||
35
uni_modules/pinia-plugin-unistorage/src/index.ts
Normal file
35
uni_modules/pinia-plugin-unistorage/src/index.ts
Normal 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);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user