之前封装的方法,基本都是通过父子组件互相调用各自的方法来实现的,还得写一大版的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 的链式调用,比较简单,也比较好用