收起
展开
代码:
useResizeObserverHooks.js
import { useEffect, useLayoutEffect } from "react";
export const useResizeObserver = (containerDom, domClass, callback) => {
useLayoutEffect(() => {
let resizeObserver = null;
let dom = null;
if (typeof ResizeObserver !== "undefined") {
// 选择你想要观察的元素
const container = containerDom || document;
dom = container.querySelector(domClass);
// 创建一个 ResizeObserver 实例并传入回调函数
resizeObserver = new ResizeObserver(entries => {
// 循环遍历所有观察到变化的元素
for (const entry of entries) {
const height = entry.target.offsetHeight;
callback(height);
}
});
// 开始观察元素
if (dom) {
resizeObserver?.observe(dom);
}
} else {
console.log("ResizeObserver is not supported in this browser.");
}
return () => {
if (dom) {
resizeObserver.unobserve(dom);
resizeObserver?.disconnect(dom);
}
};
}, [containerDom, domClass, callback]);
};
import React, { useState } from "react";
import { Button, ConfigProvider, Space, Form, Flex } from "antd";
import styles from "./Index.module.less";
import { useResizeObserver } from "./useResizeObserverHooks";
const classnames = (...args) => {
return args.filter(Boolean).join(" ");
};
const SearchForm = props => {
const {
defaultHeight = 58,
children,
onResetHandle,
buttomSolt,
submitText = "查询",
resetText = "重置",
...FromProps
} = props;
// const [form] = Form.useForm();
// console.log(buttomSolt, "buttomSolt");
const [showMore, setShowMore] = useState(false);
const containerRef = useRef(null);
useResizeObserver(containerRef.current,".ant-form", h => {
setShowMore(h > defaultHeight);
});
const onReset = () => {
// form.resetFields();
onResetHandle && onResetHandle();
};
const [isOpen, setIsOpen] = useState(false);
return (
<div
ref={containerRef}
style={{ height: `${isOpen ? "auto" : `${defaultHeight}px`}` }}
className={classnames(
styles.searchForm,
!isOpen ? styles.overflowhidden : "",
)}>
<ConfigProvider
theme={{
token: {
borderRadius: 4,
},
}}>
<Form {...FromProps}>
<div className={styles.formItemBox}>{children}</div>
<div
className={styles.ButtonBox}
style={{
paddingBottom: `${isOpen ? "" : "4px"}`,
height: `${isOpen ? "auto" : `${defaultHeight}px`}`,
}}>
<Form.Item>
{buttomSolt ? (
buttomSolt
) : (
<>
<Button htmlType="button" onClick={onReset}>
{resetText}
</Button>
<Button type="primary" htmlType="submit">
{submitText}
</Button>
</>
)}
</Form.Item>
</div>
</Form>
</ConfigProvider>
{/* 展开 收起 */}
{isOpen ? <div className={styles.zhanweibefore}></div> : null}
{showMore ? (
<div
className={isOpen ? styles.before : styles.topBefore}
onClick={() => {
setIsOpen(e => !e);
}}>
<div></div>
</div>
) : null}
</div>
);
};
export default SearchForm;
样式
.overflowhidden {
overflow: hidden;
}
.searchForm {
color: #666666;
position: relative;
.formItemBox {
display: flex;
align-items: flex-start;
justify-content: flex-start;
flex-wrap: wrap;
flex: 1;
}
.topBefore {
position: absolute;
bottom: 0;
background: #fff;
border-bottom: 1px solid #dce6ec;
width: 100%;
display: flex;
justify-content: center;
cursor: pointer;
> div {
width: 74px;
height: 4px;
background: #b3d9ff;
position: relative;
cursor: pointer;
&::before {
content: "";
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 10px solid #b3d9ff;
position: absolute;
top: -2px;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.zhanweibefore {
width: 100%;
height: 14px;
}
.before {
position: absolute;
bottom: 0;
background: #fff;
width: 100%;
height: 14px;
display: flex;
justify-content: center;
border-top: 1px solid #dce6ec;
> div {
width: 74px;
height: 4px;
background: #b3d9ff;
position: relative;
cursor: pointer;
&::before {
content: "";
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 10px solid #b3d9ff;
position: absolute;
top: 7px;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.ButtonBox {
width: 200px;
height: 100%;
display: flex;
align-items: flex-end;
justify-content: flex-end;
:global {
.ant-btn {
padding: 4px 10px;
margin-right: 10px;
}
// 重置插槽内样式
.ant-form-item-control-input-content {
align-items: flex-end;
justify-content: flex-end;
}
}
}
:global {
.ant-form {
// padding-right: 200px;
position: relative;
}
.ant-form-item {
display: flex;
align-items: center;
width: 290px;
margin: 0;
padding: 10px 15px 10px 0;
}
.ant-row {
flex: 1;
.ant-form-item-label {
width: 90px;
}
.ant-form-item-control {
flex: 1;
}
.ant-form-item-control-input-content {
display: flex;
.flex1 {
flex: 1;
}
.flex2 {
flex: 2;
}
}
}
.ant-space-compact {
flex: 1;
align-items: center;
}
.ant-picker,
.ant-input-number {
width: 100%;
}
.span2 {
width: 580px;
}
.ant-slider {
width: 100%;
}
}
}
使用
查看Antd Form api
className="span2"
className="flex2"
className="flex1"
import React, { useState, useEffect } from "react";
import styles from "./index.module.less";
import SearchForm from "@/components/SearchForm";
import HocAntdTable from "@/components/HocAntdTable";
import {
Form,
Space,
Tag,
Button,
Cascader,
Checkbox,
ColorPicker,
DatePicker,
Input,
InputNumber,
Radio,
Select,
Slider,
Switch,
TreeSelect,
Upload,
} from "antd";
const { RangePicker } = DatePicker;
const { TextArea } = Input;
const mockDataSource = Array.from({ length: 20 }, (_, index) => ({
key: (index + 1).toString(),
firstName: ["John", "Jim", "Joe"][index % 3],
lastName: ["Brown", "Green", "Black"][index % 3],
age: [32, 42, 32][index % 3],
address: [
"New York No. 1 Lake Park",
"London No. 1 Lake Park",
"Sydney No. 1 Lake Park",
][index % 3],
tags: [["nice", "developer"], ["loser"], ["cool", "teacher"]][index % 3],
}));
const dataSource = [
...mockDataSource,
{
key: "1",
firstName: "John",
lastName: "Brown",
age: 32,
address: "New York No. 1 Lake Park",
tags: ["nice", "developer"],
},
{
key: "2",
firstName: "Jim",
lastName: "Green",
age: 42,
address: "London No. 1 Lake Park",
tags: ["loser"],
},
{
key: "3",
firstName: "Joe",
lastName: "Black",
age: 32,
address: "Sydney No. 1 Lake Park",
tags: ["cool", "teacher"],
},
{
key: "11",
firstName: "John",
lastName: "Brown",
age: 32,
address: "New York No. 1 Lake Park",
tags: ["nice", "developer"],
},
{
key: "22",
firstName: "Jim",
lastName: "Green",
age: 42,
address: "London No. 1 Lake Park",
tags: ["loser"],
},
{
key: "33",
firstName: "Joe",
lastName: "Black",
age: 32,
address: "Sydney No. 1 Lake Park",
tags: ["cool", "teacher"],
},
];
const columns = [
{
title: "姓名",
dataIndex: "name",
key: "name",
},
{
title: "年龄",
dataIndex: "age",
key: "age",
},
{
title: "住址",
dataIndex: "address",
key: "address",
},
];
const FormTableDemoPage = props => {
const [form] = Form.useForm();
const aa = () => {
form.resetFields();
};
return (
<>
{/* 表单搜索 对照antd Api通用 */}
<SearchForm
labelAlign="left"
layout="inline"
onFinish={values => {
console.log(values);
}}
form={form}
onFieldsChange={(changedFields, allFields) => {
console.log(changedFields, allFields);
}}
onResetHandle={() => {
// 重置事件
form.resetFields();
}}
// buttomSolt = {
// <div>
// <Button>重置</Button>
// <Button>定义</Button>
// </div>
// }
>
<Form.Item
className="span1"
label="Checkbox"
name="disabled"
valuePropName="checked">
<Checkbox>Checkbox</Checkbox>
</Form.Item>
<Form.Item label="Address">
<Space.Compact>
<Form.Item
name={["address", "province"]}
noStyle
rules={[
{
required: true,
message: "Province is required",
},
]}>
<Select placeholder="Select province">
<Option value="Zhejiang">Zhejiang</Option>
<Option value="Jiangsu">Jiangsu</Option>
</Select>
</Form.Item>
<Form.Item
name={["address", "street"]}
noStyle
rules={[
{
required: true,
message: "Street is required",
},
]}>
<Input
style={{
width: "50%",
}}
placeholder="Input street"
/>
</Form.Item>
</Space.Compact>
</Form.Item>
<Form.Item label={null} name="ssss">
<Select className="flex1">
<Select.Option value="demo">Demo</Select.Option>
<Select.Option value="222">Demo</Select.Option>
</Select>
<Select className="flex2" name="demo">
<Select.Option value="demo">Demo</Select.Option>
<Select.Option value="222">Demo</Select.Option>
</Select>
</Form.Item>
<Form.Item label="Radio" name="Radio">
<Radio.Group>
<Radio value="apple"> Apple </Radio>
<Radio value="pear"> Pear </Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="Input" name="Input">
<Input />
</Form.Item>
<Form.Item label="Select" name="Select">
<Select>
<Select.Option value="demo">Demo</Select.Option>
</Select>
</Form.Item>
<Form.Item label="TreeSelect" name="TreeSelect">
<TreeSelect
treeData={[
{
title: "Light",
value: "light",
children: [
{
title: "Bamboo",
value: "bamboo",
},
],
},
]}
/>
</Form.Item>
<Form.Item label="Cascader" name="Cascader">
<Cascader
options={[
{
value: "zhejiang",
label: "Zhejiang",
children: [
{
value: "hangzhou",
label: "Hangzhou",
},
],
},
]}
/>
</Form.Item>
<Form.Item label="DatePicker" name="DatePicker">
<DatePicker />
</Form.Item>
<Form.Item label="RangePicker" className="span2" name="RangePicker">
<RangePicker />
</Form.Item>
<Form.Item label="InputNumber">
<InputNumber />
</Form.Item>
<Form.Item label="Switch" valuePropName="checked" name="Switch">
<Switch />
</Form.Item>
<Form.Item label="Button">
<Button>Button</Button>
</Form.Item>
<Form.Item label="Slider">
<Slider />
</Form.Item>
<Form.Item label="ColorPicker">
<ColorPicker />
</Form.Item>
</SearchForm>
{/* 表格查看 对照antd Api通用
<HocAntdTable dataSource={dataSource} columns={columns} />*/}
</>
);
};
export default FormTableDemoPage;