如果不是想写屎堆一样的代码,如果不是想不给自己挖坑,至于吗?只能怪产品需求很大众但是是真的很🤮恶心
瑟瑟发抖
就事论事如何才简单明了的解决这夺命的连续弹框的道路上,同时希望自己的代码不是屎堆,且可以给后背乘凉呢,showTime 大佬勿喷 🐶 (狗头保命)
发布订阅+组合+控制
撸起袖子直接淦(Vue3走起)
-
想法:首先将弹框当成子集,我们只需要知道接下来的步骤需要弹出哪些弹框,将其Push到List中,然后通过Controler去迭代展示弹框的展示
-
实现单个弹框的展示逻辑(发布订阅 → 告诉Controler执行下一步操作)
首先定义一个CreatMonitorSpringView类,需要
// 弹框类型枚举
enum CreatMonitorSpringViewType {
CUSTOMS_SUCCESS, // 闯关成功
CUSTOMS_EJECT, // 闯关失败
}
class CreatMonitorSpringView {
// 当前需要弹框的集合
currtDialogs: CurrtExamples = {
creatMonitorSpringViews: []
};
type: CreatMonitorSpringViewType;
valueResolve: ((value: unknown) => void) | null = null;
value: Ref<boolean> = ref(false);
delayed = 0;
callBackCollection: CallBackState = {};
get viewControl() {
return readonly(this.value);
}
constructor(type: CreatMonitorSpringViewType, callBackAsg: CallBackState = {}, delayed = 0) {
this.delayed = delayed;
this.type = type;
this.callBackCollection = callBackAsg;
// 监听弹框
watch(this.value, async () => {
// 当值改变的回调函数
if (!this.value.value) {
this.valueResolve && this.valueResolve(null);
this.closeCallback();
} else {
if (this.callBackCollection.callback) {
const data = this.callBackCollection.callback(this.close.bind(this));
if (data instanceof Promise) {
await data;
}
}
}
});
}
// 弹出弹框或者关闭弹框
async open() {
if (this.callBackCollection.beforeCallback) {
const data = this.callBackCollection.beforeCallback(this.close.bind(this));
if (data instanceof Promise) {
const result = await data;
if (!result && typeof result === 'boolean') return;
} else {
if (!data && typeof data === 'boolean') return;
}
}
return new Promise((resolve) => {
this.value.value = true;
this.valueResolve = resolve.bind(this);
});
}
close() {
this.value.value = false;
}
// 关闭回调
async closeCallback() {
if (this.callBackCollection.afertCallback) {
const data = this.callBackCollection.afertCallback(this.currtDialogs);
if (data instanceof Promise) {
await data;
}
}
this.valueResolve = null;
}
}
通过监听value值的变化,去设立钩子函数
interface CallBackState {
beforeCallback?: (Function, ...asg: any[]) => Promise<boolean | void> | boolean | void;
callback?: (Function, ...asg: any[]) => unknown;
afertCallback?: (item: CurrtExamples) => unknown;
}
最后将控制权交给Controler
const useGeneratorView = (creatMonitorSpringViews: CreatMonitorSpringView[]) => {
const currtSprType = ref<CreatMonitorSpringViewType>();
const taskCallView = async (callback?) => {
// 避免Ref转化成ToRef 且不丢响应
const currtExample = { creatMonitorSpringViews };
for (const item of currtExample.creatMonitorSpringViews) {
// 注入当前的dialog所有弹框, 防止动态逻辑需要新增弹框
currtSprType.value = item.type;
item.currtDialogs = currtExample;
await delayedPromiseFun(item.delayed);
await item.open();
}
callback && callback();
};
return { taskCallView, currtSprType };
};
const delayedPromiseFun = (delay = 0) => new Promise((resolve) => setTimeout(resolve, delay));
这样我们只需关注需要哪些弹框的展示塞入即可
useGeneratorView([
new CreatMonitorSpringView(CreatMonitorSpringViewType.CUSTOMS_SUCCESS),
new CreatMonitorSpringView(CreatMonitorSpringViewType.CUSTOMS_EJECT)
]);