antd中 React+Model 实现封装链式调用

之前封装的方法,基本都是通过父子组件互相调用各自的方法来实现的,还得写一大版的HTML .真的是超级麻烦,想了想,要是放在 JS/ TS 中进行调用就好了,不用写那么多的HTMl ,上代码

 index.tsx 文件中

import { Modal } from "antd";
import { createRef, useState } from "react";
import ReactDOM from "react-dom/client";
import "./index.scss";
import { propTypes } from "./type";

function ModelComponent(props: propTypes) {
  // 子组件需要配合 forwardRef 包裹,使用 useImperativeHandle 导出对应的数据
  let ChildRef = createRef();
  const [open, setOpen] = useState(true);
  const { component: Content, componentOptions = {} } = props;
  const Ok = () => {
    const { beforeClose } = props;
    const data = ChildRef ? ChildRef.current : {};
    const show = beforeClose ? beforeClose(data) : false;
    setOpen(show);
  };
  const cancel = () => {
    setOpen(false);
  };
  return (
    <Modal open={open} onOk={Ok} onCancel={cancel} {...props}>
      {<Content ref={ChildRef} {...componentOptions} ok={Ok} cancel={cancel} />}
    </Modal>
  );
}

export default function CreateModel(props: propTypes) {
  let container = document.createElement("div");
  document.body.appendChild(container);
  props = {
    maskClosable: false,
    destroyOnClose: true,
    footer: props.footer,
    okText: props.okText || "确定",
    cancelText: props.cancelText || "取消",
    width: props.width || "auto",
    bodyStyle: {
      ...props.bodyStyle,
      height: props.bodyStyle?.height || "auto",
    },
    ...props,
  };
  ReactDOM.createRoot(container).render(<ModelComponent {...props} />);
}

组件中使用,就需要注意了,这样子调用

import { Select } from "antd";
import React, { useRef, useState } from "react";
import { workbenchList } from "./params";
import "./index.scss";
import CreateModel from "@/global/createModel/index";
import children from "@/test";

export default function Staging() {

  function clickItem(item: any) {
    CreateModel({
      title: "新增",
      keyboard: true,
      width: 1800,
      bodyStyle: {
        height: "710px",
        overflowY: "scroll",
      },
      component: Children,
      beforeClose: (data: { start: Function }) => {
        // 注意,我这里 children 是函数式组件,类组件应该也行,可能需要改良一下即可,很简单的
        // 这里的data 其实是子组件中暴露出来的方法,我已经在 index.tsx 中处理了,data  其实等价于 childrenRef 中暴露出来的方法,指针都是一样的
        console.log("data", data);
        return true;
      },
    });
  }
  return ( 
    <div className=" bg-[white]" onClick={clickItem}>
    </div>
  );
}

child 组件中,需要通过 forwardRef ,包裹,形成高阶组件,然后,还得通过 useImperativeHandle 暴露出对应的变量,或者方法,上代码


import React, { forwardRef, useImperativeHandle, useState } from "react";


export default forwardRef(function Children(props, ref) {

  // 暴露数据
  useImperativeHandle(ref, () => ({
            test:'测试代码'
            addTask
        }));


  // 新增任务
  function addTask(type: string) {
  }

  return (
    <div className="ChildrenContainer">
    
    </div>
  );
});

基本就是这样了,也能够直接在子组件中直接调用弹窗的关闭方法,感觉还是挺好用的,只需要在组件上加你想要你的属性即可,明天在整一下 Vue 的链式调用,比较简单,也比较好用

猜你喜欢

转载自blog.csdn.net/zq18877149886/article/details/130394466