首页 > 其他分享 >让弹窗更易于使用~

让弹窗更易于使用~

时间:2023-06-02 17:14:15浏览次数:47  
标签:function hide return 易于 modal 使用 const 弹窗

标题又名:简单弹窗、多弹窗、复杂弹窗怎么做代码和状态的解耦。

关键字:react / modal

问题

实际业务中,不乏弹窗组件中包含大量复杂的业务逻辑。如:

function Order() {
    // 省略上百行方法状态
    const [visible,setVisible] = useState(false)
    const withModalState = useState<any>()
    
    return (
        <Modal>
            <Input/>
            <Input/>
            <Select/>
            <Checkbox/>
        </Modal>
    ) 
}

甚至还有多弹窗的情形。如:

function Order() {
    // 省略上百行方法状态
    const [visible1,setVisible1] = useState(false)
    const [visible2,setVisible2] = useState(false)
    const [visible3,setVisible3] = useState(false)
    
    const withModalState1 = useState<any>()
    const withModalState2 = useState<any>()
    const withModalState3 = useState<any>()
    
    // 省略 不懂多少 handlexx
    return (
        <main>
            ...
            <Modal1></* 省略很多代码 */></Modal1>
            <Modal2></* 省略很多代码 */></Modal3>
            <Modal3></* 省略很多代码 */></Modal3>
        </main>
    ) 
}
​

非常的痛:

  1. 如果弹窗在处理完内部流程后,又还有返回值,这有又会有一大通的处理函数。
  2. 如果这些代码都写在一个文件中还是不太容易维护的。

而且随着业务的断增长,每次都这么写还是很烦的。

期望的使用方式

因此有没有一种更贴近业务实际的方案。

让弹窗只专注于自己的内部事务,同时又能将控制权交给调用方呢。

或者说我就是不喜欢 Modal 代码堆在一起……

如下:

// Modal1.tsx
export function Modal1(props) return <Modal></* ... */></Modal>

// 甚至可以将MOdal中的逻辑做的更聚合。通过2次封再导出给各方使用
export const function Check_XXX_Window() {/* */ return open(Modal1)}
export const function Check_XXX_By_Id_Window() { return open(Modal1)}
export const function Check_XXX_Of_Ohter_Window() { return open(Modal1)}

// Order.tsx
function Order() {

    function xxHndanle { 
        const expect = Check_XXX_Window(Modal1,args) // 调用方法,传入参数,获得预期值 ,完成1个流程
    }
    return (
        <main>
            ...
            // 不实际挂载 Modal 组件
        </main>
    ) 
}

像这样分离两者的代码,这样处理起来肯定是清爽很多的。

实现思路

实现的思路都是一致的。

  1. 创建占位符组件,放到应用的某处。
  2. 将相关状态集管理,并与Modal做好关联。
  3. 暴露控制权。

因此基于不同的状态管理方案,实现是多种多样的。相信很多大佬都自己内部封装过不少了。

但是在此基础上,我还想要3点。

  1. API使用简单,但也允许一定配置。
  2. 返回值类型推导,除了帮我管理 close 和 open 还要让我用起来带提示的。
  3. 无入侵性,不依赖框架以外的东西。

ez-modal-react

emm......苦于市面上找不到这类产品(感觉同类并不多……讨论的也不多?)

于是我自己开源了一个。回应上文实现思路,可以点击看代码,几百行而已。

并不是突发奇想而来,其实相关特性早就在企业内部是使用多年了。我也是受前辈和社区启发。

基本特性

  1. 基于Promise封装
  2. 返回值类型推导
  3. 没有入侵性,体积小。

使用画面

import EasyModal, { InnerModalProps } from 'ez-modal-react';

+ interface IProps extends InnerModalProps<'fybe?'> /*传入返回值类型*/ {
+   age: number;
+   name: string;
+ }

export const InfoModal = EasyModal.create(
+ (props: Props) => {
  return (
    <Modal
      title="Hello"
      open={props.visible}
      onOk={() => {
+       props.hide(); // warn 应有 1 个参数,但获得 0 个。 (property) hide: (result: "fybe?") => void ts(2554)
      }}
      onCancel={() => {
       props.hide(null); //safe hide 接受 null 作为参数。它兼具 hide resolve 两种功能。
      }}
    >
      <h1>{props.age}</h1>
    </Modal>
  );
});

+ // warn 类型 "{ name: string; }" 中缺少属性 "age",但类型 "ModalProps<Props, "fybe?">" 中需要该属性。
EasyModal.show(InfoModal, { name: 'foo' }).then((resolve) => {
  console.log(resolve);
+ //输出 "fybe?" 
});

也支持用 hook

import EasyModal, { useModal, InnerModalProps } from 'ez-modal-react';

interface IProps extends InnerModalProps<'苏振华'>/* 指定返回值类型 */ {
  age: number;
  name: string;
}

export const Info = EasyModal.create((props: Props) => {
  const modal = useModal<Props>(); 

  function handleOk(){
      modal.hide(); // ts(2554) (property) hide: (result: "苏振华") => void ts(2554)
  } 

  return  <Modal open={modal.visible} onOk={handleOk} onCancel={modal.hide}></Modal>
});


EasyModal.show(Info,{age:18,}) // 缺少属性 "age"

还有一些特性如支持配置 hide 弹窗时的默认行为。(我认为大多数情况下可能用不上)


export const Info = EasyModal.create((props: Props) => {
  const modal = useModal<Props>(); 

  function handleOk(){
      modal.hide(); 
+     modal.resolve('苏振华') // 需要手动抛出成功
+     modal.remove() // 需要手动注销组件。可用于反复打开弹窗,但是不希望状态被清除的场景。
  } 

  return  <Modal open={modal.visible} onOk={handleOk} onCancel={modal.hide}></Modal>

// Ohter.tsx
EasyModal.open(Info, {},
+  config:{
+    resolveOnHide:false, // 默认为 true
+    removeOnHide:false,  // 默认为 true
+  }
);

当然以上是针对弹窗内有复杂业务场景的状况。

大部分场景都是调用方只在乎 open或close ,仅仅解耦代码这一项好处,就可以让代码变得清爽。

如常用的有展示类,设置类的弹窗,TS类型都用不上。

仓库

其他就不一一介绍了,主要的已经说完了,想了解更多,可以看看仓库。github

标签:function,hide,return,易于,modal,使用,const,弹窗
From: https://www.cnblogs.com/coderao/p/17452339.html

相关文章

  • SVN基本使用
    SVN协同开发工具(版本控制器)目前使用最广泛的就是svn和git主要作用:管理项目的版本,多人协同开发svn和git帮我们管理项目svn:集中式git:分布式安装SVN打开服务器:注意事项:svn的服务器默认是80端口,所以和xampp的端口冲突推荐修改svn服务器端口:打开服务器端找一个......
  • 如何使用Spring管理Filter和Servlet
    在使用spring容器的web应用中,业务对象间的依赖关系都可以用context.xml文件来配置,并且由spring容器来负责依赖对象的创建。如果要在filter或者servlet中使用spring容器管理业务对象,通常需要使用WebApplicationContextUtils.getRequiredWebApplicationContext......
  • EasyCVR使用SDK接入,设备全部离线,但是SDK DEMO接入正常是什么原因?
    EasyCVR视频融合平台基于云边端一体化架构,具有强大的数据接入、处理及分发能力,平台支持多协议、多类型的设备接入,包括主流标准协议国标GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。有用户反馈,EasyCVR平台中,使用SDK接入的设备显示全......
  • 两条宽带(移动、电信)如何同时使用的一种方法,一点都不浪费。
    原本我有一根电信的300M宽带,用着还行。但烦恼都是自找的,起因是我去移动换了手机套餐,移动非要送我一条宽带,然后免我宽带月租20元,不办宽带没有优惠(-50)。这办个宽带还能多优惠30元,可以的!果断答应了。办了宽带然后烦恼就找上门了,我只能使用一条线,多了宽带也只能放那浪费!因为只有电......
  • 使用ILMerge将多个DLL整合进winform程序
    ILMerge是微软开发的工具用于将多个dll、exe等合并,项目已经开源在github 命令行方式使用范例:ILMerge.exe /ndebug/target:winexe/out:output.exe1.exe1.dll2.dll3.dll......
  • Qt第六十二章:图标库QtAwesome的使用
    目录一、安装依赖二、主页三、文档四、案例1、图标2、样式3、alpha通道4、多图标堆叠5、动画6、字体五、系列1、msc系列2、fa5系列(选择free栏)3、fa5s系列(选择free栏)4、fa5b系列(选择free栏)5、fa系列6、ei系列7、mdi系列8、mdi6系列9、ph系列10、ri系列一、安装依赖pipinstallQtA......
  • k8s 使用crio,pod ip无法ssh登录,无法使用ping命令
    使用crio容器运行时,部署sshpod后,sshroot@127.0.0.1后,出现connectionresetby127.0.0.1port22.但是telnet显示能通,在pod中ping其他pod出现socket:Operation not permitted,权限问题。通过测试在contianerd与docker没出现这个问题,基本上与crio有关了。......
  • 使用php easydamin
    #installcomposer[root@izbpot8zbin]#curl-sShttps://getcomposer.org/installer|phpAllsettingscorrectforusingComposerDownloading...#movefileComposer(version2.5.7)successfullyinstalledto:/usr/bin/composer.pharUseit:phpcomposer.phar[root......
  • Python中动态导入对象importlib.import_module()的使用
    参考:https://blog.csdn.net/edward_zcl/article/details/88809212https://www.cnblogs.com/yhjoker/p/15969508.html经常在项目中碰到需要根据配置动态导入不同的类的方法进行运行,这时就要用动态函数import_module的使用方法假设项目目录结构如下: ......
  • unordered_map、unordered_set使用
    unordered_map头文件#include<iostream>#include<unordered_map>usingnamespacestd;增删查改unordered_map底层实现为哈希表,增删效率与查找效率都是O(1)增加元素emplace(key,value)insert(pair<T,T>p)数组修改法//unordered_map三种增加元素的方式// insert(......