前端实现Mobx+TypeScript+持久化存储
Mobx+Ts+持久化存储是一种强大的前端开发组合,它结合了 Mobx 状态管理、TypeScript 类型检查和持久化存储技术。Mobx 是一款功能丰富且易于使用的状态管理库,通过提供响应式的数据流和简洁的语法,有效解决了复杂应用中的数据管理问题。TypeScript 作为静态类型检查工具,可以帮助开发者在编码阶段捕获类型错误和提供智能提示,提高代码的可维护性和可读性。而持久化存储技术则可以将应用的数据长期保存,保证用户数据的可靠性和持续性。通过结合这三者,开发者可以构建出更健壮、可靠的前端应用。
封装 Store
HomeStore 示例
import { makeAutoObservable, runInAction } from "mobx";
import { setResult } from "@utils/util";
import { getTaskPendingApi } from "@/apis/modules/firstPage/firstPage.api";
import { toJS } from "mobx";
class HomeStore {
taskPendingList = {
count: 0,
list: [],
};
reminderCount: any = {
total: 0,
};
constructor() {
makeAutoObservable(this);
}
// 获取待办列表
async getTaskPending(data) {
const resultObj = {
api: getTaskPendingApi,
apiParams: data,
loading: "riskLoading",
result: "taskPendingList",
};
await setResult.call(this, resultObj);
}
// 清空消息数量
countEmpty() {
runInAction(() => {
this.reminderCount = {};
console.log("清空消息数量", toJS(this.reminderCount));
});
}
}
export default new HomeStore();
在构造函数中调用了makeAutoObservable(this),这个函数来自 MobX 库,用于将类实例中的属性和方法转换为可观察的对象,使其能够被 MobX 追踪并自动更新相关组件。
setResult 方法
/*
* 处理 store
* @param api 调用后端 api 接口
* @param apiParams 接口需要传递的参数
* @param loading 涉及到的 loading 状态属性名称
* @param result 需要修改的结果属性名称
* @param msg 调用接口成功提示信息
* @param ifConsole 是否打印调用接口信息到控制台
* @param callback 回调函数,用于处理接口返回结果
* @returns {Promise<any>}
*/
export async function setResult(this: any, {
api,
apiParams,
loading,
result,
msg,
ifConsole = false,
callback
}: any): Promise<any> {
if (typeof loading === "string" && loading.length > 0) {
this[loading] = true;
}
try {
const res = await api(apiParams);
runInAction(() => {
if (typeof loading === "string" && loading.length > 0) {
this[loading] = false;
}
if (typeof result === "string" && result.length > 0) {
this[result] = callback ? callback(res) : res;
}
});
if (ifConsole) {
console.log({ api, res });
}
if (msg) {
message.success(msg);
}
return await Promise.resolve(res)
} catch (e) {
runInAction(() => {
if (typeof loading === "string" && loading.length > 0) {
this[loading] = false;
}
});
if (ifConsole) {
console.log({ api, e });
}
await Promise.reject(e)
}
}
函数setResult接收一个对象作为参数,包含了调用后端 API 所需的各种信息,如 API 函数、参数、loading 状态属性名称、结果属性名称等。具体来说,它的参数如下:
api:后端 API 接口函数。apiParams:调用 API 时传递的参数。loading:涉及到的 loading 状态属性的名称。result:需要修改的结果属性的名称。msg:调用接口成功时的提示信息。ifConsole:一个布尔值,指示是否将调用接口信息打印到控制台。callback:一个回调函数,用于处理接口返回结果。
函数首先根据传入的loading参数设置相应的 loading 状态属性,然后调用后端 API,并在获取到结果后使用runInAction函数修改状态属性。如果设置了msg,则会显示成功提示信息。最后,根据ifConsole参数决定是否将调用接口信息打印到控制台。
如果调用过程中出现了错误,函数会在catch块中处理,并同样根据需要修改 loading 状态属性和打印错误信息。
这个函数是一个通用的、用于调用后端 API 并处理结果的辅助函数。
持久化存储示例
import { makeAutoObservable, runInAction } from "mobx";
import { makePersistable } from "mobx-persist-store";
import { getEnumApi } from "@apis/common.api";
import { formatEnumList, setResult, handleLocalForage } from "@utils/util";
class CommonStore {
enumList: any = {};
appProvider: any = {};
constructor() {
makeAutoObservable(this, {
isModuleEnum: false,
});
//持久化存储
makePersistable(this, {
name: "enumList",
properties: ["enumList"],
storage: handleLocalForage,
});
}
get isModuleEnum() {
const list = window.location.pathname.split("/");
const pathname = `/${list[1]}`;
return formatEnumList(this.enumList.data[pathname]);
}
saveAppProvider(appProvider: any) {
runInAction(() => (this.appProvider = appProvider));
}
async getEnumList(data: any) {
const resultObj = {
api: getEnumApi,
results: "enumList",
apiParams: data,
};
await setResult.call(this, resultObj);
}
}
export default new CommonStore();
akeAutoObservable函数用于将类实例的属性和方法转换为可观察的,并自动追踪其变化。在这个例子中,makeAutoObservable被调用时,第一个参数是当前类的实例this,而第二个参数是一个对象,用于指定哪些属性或方法不应该被自动转换为可观察的。makePersistable是 MobX Persist Store 库中提供的一个函数,用于将 MobX store 中的特定属性持久化到本地存储中,以便在应用程序重新加载时恢复它们的状态。它的主要作用是确保应用程序在重新加载后能够保持之前的状态,并且不会丢失任何重要的数据。name:保存的 name,用于在 storage 中的名称标识,只要不和 storage 中其他名称重复就可以properties:要保存的字段,这些字段会被保存在 name 对应的 storage 中,注意:不写在这里面的字段将不会被保存,刷新页面也将丢失:get 字段例外。get 数据会在数据返回后再自动计算storage:保存的位置:看自己的业务情况选择,可以是 localStorage,sessionstorage
封装 useStores
import React from "react";
import { MobXProviderContext } from "mobx-react";
interface ContextType {
stores: StoreType;
}
//函数声明,重载
function useStores(): StoreType;
function useStores<T extends keyof StoreType>(storeName: T): StoreType[T];
/*
*获取根 store 或者指定 store 名称数据
*@param storeName 指定了 store 名称
*@returns typeof StoreType[storeName]
*/
function useStores<T extends keyof StoreType>(storeName?: T) {
const rootStore = React.useContext(MobXProviderContext);
const { stores } = rootStore as ContextType;
return storeName ? stores[storeName] : stores;
}
export { useStores };
/**
*获取所有模块 store
*/
const files = Object.entries(
import.meta.glob("./modules/**/*.ts", { eager: true })
);
const _store: any = {};
files.forEach((item: any) => {
const key = `${item[0].split("/").at(-1).split(".")[0]}Store`;
_store[key] = item[1].default;
});
export type StoreType = typeof _store;
export default _store;
Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块,并且在构建时将它们分离为独立的 chunk。这种方式默认是异步加载模块的,通过动态导入实现。你可以遍历生成的 modules 对象的键来访问相应的模块。
如果你希望直接引入所有的模块(同步加载使用),你可以传入 { eager: true } 作为第二个参数。这样,模块会被转译为直接引入的形式。
示例:
下面是你提供的示例代码以及它们在构建时被转译成的代码:
// 原始代码示例
const modules = import.meta.glob('./dir/*.js')
for (const path in modules) {
modules[path]().then((mod) => {
console.log(path, mod)
})
}
在构建时,上述代码会被转译成:
// 转译后的代码示例
const modules = {
'./dir/foo.js': () => import('./dir/foo.js'),
'./dir/bar.js': () => import('./dir/bar.js')
}
for (const path in modules) {
modules[path]().then((mod) => {
console.log(path, mod)
})
}
另外,如果你希望以同步加载的形式引入所有的模块,你可以这样写:
javascriptCopy Code// 原始代码示例
const modules = import.meta.glob('./dir/*.js', { eager: true })
// 转译后的代码示例
import * as __glob__0_0 from './dir/foo.js'
import * as __glob__0_1 from './dir/bar.js'
const modules = {
'./dir/foo.js': __glob__0_0,
'./dir/bar.js': __glob__0_1
}
这样,所有模块会被转译成直接引入的形式,而不是通过动态导入异步加载。
导入使用
main.js 全局导入
import { observer, Provider } from 'mobx-react'
import stores from '@/stores'
function Main() {
return <Provider stores={ stores }> {/* 应用的其余部分 */ } < /Provider>
}
export default observer(Main)
组件中使用
import { observer } from "mobx-react";
import { useEffect } from "react";
import { useStores } from "@/stores";
const FirstPage = () => {
const { homePageStore } = useStores();
useEffect(() => {
homePageStore.getEnumsList();
}, []);
return <></>;
};
export default observer(FirstPage);
结语
以上就是关于 Mobx+Ts+持久化存储的全部内容,希望对大家有用,更多精彩内容请关注码云笔记。
以上关于前端实现Mobx+TypeScript+持久化存储的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 前端实现Mobx+TypeScript+持久化存储

微信
支付宝