在store下建个文件夹,文件夹里存放index.ts和reducer.ts
index.ts
const store: storeObject = {
state: {
// 放数据
num: 20,
},
actions: {
// 只放同步的方法
add1(newState: { num: number }, action: { type: string }) {
newState.num++;
},
add2(newState: { num: number }, action: { type: string; val: number }) {
newState.num += action.val;
},
},
异步方法
asyncActions: {
// 只放异步的方法
asyncAdd1(dispatch: Function) {
setTimeout(() => {
dispatch({ type: "add1" });
}, 1000);
},
},
actionNames: {},
};
// 我们现在想做到actionNames自动生成。不用每一次添加一个方法,都要在actionNames手动添加键值对,这样很麻烦。
let actionNames: NObject = {}; // 定义一个全局的actionNames
// actionNames有多少对键值对,取决于action里面有多少个函数。所以遍历store.actions,给actionNames添加键值对
for (let key in store.actions) {
actionNames[key] = key;
}
store.actionNames = actionNames;
export default store;
// 封装的目的:最终是有利于我们的开发或者维护
// 封装的思路是:将来开发的时候只需要把数据写和方法写入到这个状态文件中,例如:XxxxStatus/index.ts,而不需要再去操作其他的文件。(我们往这个方向去封装)
reducer.ts
import handleNum from "./index";
// 就是来管理数据的
let reducer = (
state = { ...handleNum.state },
action: { type: string }
) => {
let newState = JSON.parse(JSON.stringify(state));
// 拿着action.type和actionNames进行每一项的对比,如果是相等,就调用 模块名.actions[下标](newState,action)
for (let key in handleNum.actionNames) {
// key是每一个键
// 判断是不是相等
// if(action.type==="add1"){
if (action.type === handleNum.actionNames[key]) {
handleNum.actions[handleNum.actionNames[key]](newState, action);
break;
}
}
// 这样写就达到每一次写一个方法都不需要再手动来添加这几case,终于可以解放双手了!
return newState;
};
export default reducer;
如果以后有新增方法,只需在index.ts中添加对应的action,无需修改reducer.ts.
调用时,调同步方法
dispatch({ type: "add1", val: 10 });
调异步方法
dispatch((dis: Function) => {
setTimeout(() => {
dis({ type: "add1" });
}, 1000);
});