基于MUI实现的全局Dialog API

这篇博客介绍了如何基于MUI构建一个全局Dialog API,减少了重复代码,提供了一个全局调用的Hook。作者通过MVC设计模式,详细阐述了Model、View和Controller层的实现,包括使用Recoil的状态管理以及不使用状态管理库时通过Observable同步状态的方法。
摘要由CSDN通过智能技术生成

概述

在最近使用 MUI 的过程中,我突然发现 MUI 的 Dialog 好像没有如同 Arco Design 那样自带命令式调用方法,这个缺失的特性导致我在使用 Dialog 时(即便我只是想很简单地显示一点提示信息),必须显式地在 UI 中声明一个 Dialog 组件。

编写重复代码的过程其实是非常痛苦的,而当重复的代码慢慢累积起来之后,核心代码的可读性也会受到一定的影响。

为了减少编写重复代码的时间,我想使用”池化“的思维来构建一个全局的临时 Dialog 组,同时提供一个可以在全局进行调用的 Hook,把展示临时 Dialog 的声明缩略到一条语句以内。

外部依赖

  • React* MUI* Recoil(可选,不想用状态管理库的话,本文也提供了一种通过手写 Observable 同步全局状态的办法)仓库
    ==

有人可能更喜欢从源码入手去理解逻辑,这里先把 Demo 的仓库丢出来:

GitHub - sheason2019/global-dialog-demo

起步

为了节省时间,一些比较基础的部分我就不讲的太细了。

在开始正式编码之前,我们首先需要使用Vite搭建起一个基础的 React-Typescript 框架,然后将 React、MUIRecoil这三个依赖库添加至项目。

方便起见,这里把除了 React 以外的安装页面链接都附在了上面的超链接文本里。

分析需求

在上面的概述中,我提到了我希望在使用 MUI 时能像使用 Arco Design 一样通过命令式的方式调用 Dialog,从而提升开发体验和代码结构。

根据这个核心的需要我们可以很快推导出我们需要做的事情:

 graph TD;A[命令式调用Dialog] --> B[需要提供可以全局调用的Controller];A --> G[需要提供基础的Dialog模板显示内容]G --> H[使用MUI设计View]A --> C[需要提供可以渲染Dialog的Model]B --> E[使用Hook提供API Controller]C --> F[根据需要设计Model] 

可以看到,这是一个很典型的 MVC 设计,所以,我们接下来按照最常规的 MVC 开发流程来实现这个需求即可。

Model 层的设计

在通常的 Web 程序设计中,使用 Dialog 来展示提示信息的场景多种多样,具体可以参考Arco Design - Dialog 消息展示,我们这里只实现两种最基本的 Dialog 场景:信息展示和操作确认。

首先让我们来思考一下一个最基本的 Dialog 需要声明哪些信息:

interface IGlobalDialog {// 因为采用循环渲染的方式渲染Dialog组,所以需要一个UUID来确保Dialog的Key不重复uuid: string;title: React.ReactNode;content: React.ReactNode;
} 

显然,对于一个最基础的 Dialog,我们最核心的诉求是让它能展示我们需要的标题和内容。

IGlobalDialog为基础类型,我们可以很容易地扩展出信息展示 Dialog 和操作确认 Dialog 的接口:

// 信息展示Dialog
interface IGlobalNormalDialog extends IGlobalDialog {type: "normal";
}
// 操作确认Dialog
interface IGlobalConfirmDialog extends IGlobalDialog {type: "confirm";
} 

然后,我们可以将这两个接口组合起来:

type GlobalDialogTypeCompose =| IGlobalConfirmDialogState| IGlobalNormalDialogState; 

现在,我们就得到了一个可以用来表示所有可用 Dialog 接口的接口:GlobalDialogTypeCompose

通过这个接口,我们可以基于 Recoil 创建出一个全局状态用来管理这些 Dialog:

const globalAlertDialogState = atom<GlobalDialogTypeCompose[]>({key: "common/global-alert-dialog",default: [],
}); 

到了这一步,Model 层的建设其实就已经完成的差不多了,在 React 组件内部编写相应的循环渲染逻辑后,我们就可以根据globalAlertDialogState中存储的数据启动和关闭自己需要的 Dialog。

但是!事情并没有这么简单。 在关闭 Dialog 时,如果你的操作只是简单地从globalAlertDialogState中移除掉对应的结构体,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值