diff --git a/packages/concis-react/src/DatePicker/DatePicker/index.tsx b/packages/concis-react/src/DatePicker/DatePicker/index.tsx index 6a28e128..fbe58084 100644 --- a/packages/concis-react/src/DatePicker/DatePicker/index.tsx +++ b/packages/concis-react/src/DatePicker/DatePicker/index.tsx @@ -99,9 +99,8 @@ const DatePicker: FC = (props) => { setNowDayList( chunk( daysArr.map((_, i) => { - const day = `${ - i - firstWeekDay <= -1 || i - firstWeekDay + 1 > lastDay ? '' : i - firstWeekDay + 1 - }`; + const day = `${i - firstWeekDay <= -1 || i - firstWeekDay + 1 > lastDay ? '' : i - firstWeekDay + 1 + }`; const date = new Date(year, month - 1, Number(day)); return { date, @@ -122,7 +121,7 @@ const DatePicker: FC = (props) => { }, [formCtx.reset]); useEffect(() => { if (formCtx.submitStatus) { - formCtx.getChildVal(`${dayjs(nowDate).format(format)}`); + formCtx.getChildVal(dateValue); } }, [formCtx.submitStatus]); @@ -134,7 +133,6 @@ const DatePicker: FC = (props) => { if (data.disable) { return; } - console.log(nowDayList); setClickDate(data.date); setDateValue(dayjs(data.date).format(format)); setNowDate({ @@ -218,9 +216,8 @@ const DatePicker: FC = (props) => { setInputVal(day)} - className={`${day.value === '' ? 'day-empty' : ''} ${ - day.disable ? 'disable' : '' - } ${isSameDate(day.date) ? 'active' : ''}`} + className={`${day.value === '' ? 'day-empty' : ''} ${day.disable ? 'disable' : '' + } ${isSameDate(day.date) ? 'active' : ''}`} > {day.value} @@ -239,6 +236,7 @@ const DatePicker: FC = (props) => { type="primary" showClear={showClear} clearCallback={clearCallback} + isFather /> ); diff --git a/packages/concis-react/src/DatePicker/MonthPicker/index.tsx b/packages/concis-react/src/DatePicker/MonthPicker/index.tsx index e3ec656c..479a3b44 100644 --- a/packages/concis-react/src/DatePicker/MonthPicker/index.tsx +++ b/packages/concis-react/src/DatePicker/MonthPicker/index.tsx @@ -83,7 +83,7 @@ const MonthPicker: FC = (props) => { }, [formCtx.reset]); useEffect(() => { if (formCtx.submitStatus) { - formCtx.getChildVal(`${dayjs(dateValue).format(format)}`); + formCtx.getChildVal(dateValue); } }, [formCtx.submitStatus]); const clearCallback = () => { @@ -104,9 +104,6 @@ const MonthPicker: FC = (props) => { date.getMonth() + 1 === clickDate.getMonth() + 1 ); }; - useEffect(() => { - console.log(108, dateValue); - }, [dateValue]); return ( = (props) => { setInputVal(new Date(startYear, idx * 3 + i))} - className={`${ - disableCheck(new Date(startYear, idx * 3 + i)) ? 'disable' : '' - } ${isSameDate(new Date(startYear, idx * 3 + i)) ? 'active' : ''}`} + className={`${disableCheck(new Date(startYear, idx * 3 + i)) ? 'disable' : '' + } ${isSameDate(new Date(startYear, idx * 3 + i)) ? 'active' : ''}`} > {month} @@ -165,6 +161,7 @@ const MonthPicker: FC = (props) => { type="primary" showClear={showClear} clearCallback={clearCallback} + isFather /> ); diff --git a/packages/concis-react/src/DatePicker/YearPicker/index.tsx b/packages/concis-react/src/DatePicker/YearPicker/index.tsx index d0e38a43..d8f5927f 100644 --- a/packages/concis-react/src/DatePicker/YearPicker/index.tsx +++ b/packages/concis-react/src/DatePicker/YearPicker/index.tsx @@ -96,18 +96,17 @@ const YearPicker: FC = (props) => { ), ); }, [year]); - // useEffect(() => { - // //用于监听Form组件的重置任务 - // if (formCtx.reset) { - // setNowDate(today); - // setDateValue(''); - // } - // }, [formCtx.reset]); - // useEffect(() => { - // if (formCtx.submitStatus) { - // formCtx.getChildVal(`${dayjs(nowDate).format(format)}`); - // } - // }, [formCtx.submitStatus]); + useEffect(() => { + //用于监听Form组件的重置任务 + if (formCtx.reset) { + setDateValue(''); + } + }, [formCtx.reset]); + useEffect(() => { + if (formCtx.submitStatus) { + formCtx.getChildVal(dateValue); + } + }, [formCtx.submitStatus]); const clearCallback = () => { setDateValue(''); handleChange && handleChange(null); @@ -162,9 +161,8 @@ const YearPicker: FC = (props) => { setInputVal(date)} - className={`${date.disable ? 'disable' : ''} ${ - isSameDate(date.date) ? 'active' : '' - }`} + className={`${date.disable ? 'disable' : ''} ${isSameDate(date.date) ? 'active' : '' + }`} > {date.value} @@ -182,6 +180,7 @@ const YearPicker: FC = (props) => { type="primary" showClear={showClear} clearCallback={clearCallback} + isFather /> ); diff --git a/packages/concis-react/src/Drawer/demos/index1.tsx b/packages/concis-react/src/Drawer/demos/index1.tsx new file mode 100644 index 00000000..8ea47775 --- /dev/null +++ b/packages/concis-react/src/Drawer/demos/index1.tsx @@ -0,0 +1,29 @@ +import React, { useState } from 'react'; +import Drawer from '..'; +import Button from '../../Button'; + +export default function index1() { + const [visible, setVisible] = useState(false); + + return ( +
+ + setVisible(false)} + onCancel={() => setVisible(false)} + > +

This is a Drawer view text.

+

This is a Drawer view text.

+

This is a Drawer view text.

+
+
+ ); +} diff --git a/packages/concis-react/src/Drawer/demos/index2.tsx b/packages/concis-react/src/Drawer/demos/index2.tsx new file mode 100644 index 00000000..a19b0cfa --- /dev/null +++ b/packages/concis-react/src/Drawer/demos/index2.tsx @@ -0,0 +1,40 @@ +import React, { useState, useEffect } from 'react'; +import Drawer from '..'; +import Button from '../../Button'; +import RadioGroup from '../../Radio/RadioGroup'; +import Radio from '../../Radio'; + +export default function index1() { + const [visible, setVisible] = useState(false); + const [align, setAlign] = useState('right'); + + return ( +
+ setAlign(val.children)}> + right + left + top + bottom + + + setVisible(false)} + onCancel={() => setVisible(false)} + > +

This is a Drawer view text.

+

This is a Drawer view text.

+

This is a Drawer view text.

+
+
+ ); +} diff --git a/packages/concis-react/src/Drawer/demos/index3.tsx b/packages/concis-react/src/Drawer/demos/index3.tsx new file mode 100644 index 00000000..4138b578 --- /dev/null +++ b/packages/concis-react/src/Drawer/demos/index3.tsx @@ -0,0 +1,36 @@ +import React, { useState } from 'react'; +import Drawer from '..'; +import Button from '../../Button'; + +export default function index1() { + const [visible, setVisible] = useState(false); + + return ( +
+ + { + return new Promise((resolve) => { + setTimeout(() => { + setVisible(false); + resolve(''); + }, 2000) + }) + }} + onCancel={() => setVisible(false)} + > +

This is a Drawer view text.

+

This is a Drawer view text.

+

This is a Drawer view text.

+
+
+ ); +} diff --git a/packages/concis-react/src/Drawer/demos/index4.tsx b/packages/concis-react/src/Drawer/demos/index4.tsx new file mode 100644 index 00000000..ffcfd44c --- /dev/null +++ b/packages/concis-react/src/Drawer/demos/index4.tsx @@ -0,0 +1,76 @@ +import React, { useState } from 'react'; +import Drawer from '..'; +import Button from '../../Button'; +import Space from '../../Space'; + +export default function index1() { + const [visible1, setVisible1] = useState(false); + const [visible2, setVisible2] = useState(false); + const [visible3, setVisible3] = useState(false); + const [loading, setLoading] = useState(false); + + const closeAsync = () => { + setLoading(true); + setTimeout(() => { + setVisible2(false); + setLoading(false); + }, 2000); + }; + + return ( +
+ + + + + + setVisible1(false)} + onOk={() => setVisible1(false)} + okButtonProps={{ disabled: true }} + cancelButtonProps={{ disabled: true }} + > +

This is a Drawer view text.

+

This is a Drawer view text.

+

This is a Drawer view text.

+
+ setVisible2(false)} + footer={ + + + + + + } + > +

This is a Drawer view text.

+

This is a Drawer view text.

+

This is a Drawer view text.

+
+ setVisible3(false)} + onOk={() => setVisible3(false)} + footer={<>} + > +

This is a Drawer view text.

+

This is a Drawer view text.

+

This is a Drawer view text.

+
+
+ ); +} diff --git a/packages/concis-react/src/Drawer/demos/index5.tsx b/packages/concis-react/src/Drawer/demos/index5.tsx new file mode 100644 index 00000000..44ae790a --- /dev/null +++ b/packages/concis-react/src/Drawer/demos/index5.tsx @@ -0,0 +1,30 @@ +import React, { useState } from 'react'; +import Drawer from '..'; +import Button from '../../Button'; + +export default function index1() { + const [visible, setVisible] = useState(false); + + return ( +
+ + setVisible(false)} + onCancel={() => setVisible(false)} + > +

This is a Drawer view text.

+

This is a Drawer view text.

+

This is a Drawer view text.

+
+
+ ); +} diff --git a/packages/concis-react/src/Drawer/demos/index6.tsx b/packages/concis-react/src/Drawer/demos/index6.tsx new file mode 100644 index 00000000..a791f403 --- /dev/null +++ b/packages/concis-react/src/Drawer/demos/index6.tsx @@ -0,0 +1,87 @@ +import React, { useState, createRef } from 'react'; +import Drawer from '..'; +import Button from '../../Button'; +import Form from '../../Form'; +import Input from '../../Input'; +import CheckBox from '../../CheckBox'; +import Message from '../../Message'; +import Rate from '../../Rate'; +import Space from '../../Space'; + +export default function index1() { + const [visible, setVisible] = useState(false); + const form = Form.useForm(); + const formRef = createRef(); + + const submit = async () => { + const submitParams = await form.onSubmit(formRef); + if (submitParams.submitResult) { + Message.success('注册成功'); + setVisible(false); + } else { + Message.error('注册失败'); + } + }; + + return ( +
+ + setVisible(false)} + footer={ + + + + + + } + > +
+ + + + a.includes('concis'), message: '必须包含concis' }, + ]}> + + + + + + + I have read the manual + +
+
+
+ ); +} diff --git a/packages/concis-react/src/Drawer/index.md b/packages/concis-react/src/Drawer/index.md new file mode 100644 index 00000000..3a329072 --- /dev/null +++ b/packages/concis-react/src/Drawer/index.md @@ -0,0 +1,54 @@ +--- +title: Drawer 抽屉 +nav: + title: 组件 + path: /common +group: + title: 反馈 +--- + +# Drawer 抽屉 + +触发命令后,从屏幕一侧滑出的抽屉式的面板。 + +## 基本使用 + +基础抽屉,点击触发按钮抽屉从右侧滑出,点击遮罩区关闭。 + + + +## 不同方向 + +配置`align`改变抽屉出现位置,可选`left`、`right`、`top`、`bottom`,默认为`right`。 + + + +## 异步关闭 + +支持`onCancel`、`onOk`为 Promise 写法,异步控制抽屉显示状态。 + + + +## 自定义页脚 + +传入 `okButtonProps` 和 `cancelButtonProps` 可分别自定义确定按钮和取消按钮的 `props`。如果 `okButtonProps` 、 `cancelButtonProps` 仍然不能满足需要的话,可以直接传入 `footer` 来自定义页脚内容。 + +`footer` 传入`<>`则代表无页脚。 + + + +## 自定义宽度 + +通过 `width` 配置对话框百分比宽度。 + +设置 `string` 代表 px 值,设置 `number` 代表百分比值。 + + + +## 抽屉表单 + +一个`Form` + `Drawer`的实例。 + + + + diff --git a/packages/concis-react/src/Drawer/index.tsx b/packages/concis-react/src/Drawer/index.tsx new file mode 100644 index 00000000..8aba3b5f --- /dev/null +++ b/packages/concis-react/src/Drawer/index.tsx @@ -0,0 +1,234 @@ +import React, { useState, useEffect, useRef, useContext, useMemo } from 'react'; +import lodash from 'lodash'; +import { CSSTransition } from 'react-transition-group'; +import { + CloseOutlined +} from '@ant-design/icons'; +import Button from '../Button'; +import { DrawerProps } from './interface'; +import { GlobalConfigProps } from '../GlobalConfig/interface'; +import cs from '../common_utils/classNames'; +import { globalCtx } from '../GlobalConfig'; +import useOverFlowScroll from '../common_utils/hooks/useOverFlowScroll'; +import './styles/index.module.less'; + +function isPromiseFn(fn: Function): boolean { + if (fn && fn.toString().trim().includes('new Promise')) { + return true; + } + return false; +} + +const Drawer = (props: DrawerProps) => { + const { + className, + children, + title, + visible, + align = 'right', + okButtonProps = {}, + cancelButtonProps = {}, + footer, + okText, + cancelText, + width = '320px', + onOk, + onCancel + } = props; + + const [wrapperVisible, setWrapperVisible] = useState(visible); + const [okLoading, setOkLoading] = useState(false); + const [cancelLoading, setCancelLoading] = useState(false); + const isCloseWorking = useRef(false); //正在关闭 + + const { prefixCls, darkTheme } = useContext(globalCtx) as GlobalConfigProps; + const classFirstName = darkTheme ? 'concis-dark-drawer' : 'concis-drawer'; + const classNames = cs(prefixCls, className, classFirstName); + + const clickDocumentCancel = lodash.throttle((e) => { + const clickDom = e.target as HTMLElement; + e.stopPropagation(); + if (clickDom.getAttribute('class')?.includes('concis-drawer-dialog')) { + cancel(); + } + }, 0); + + useEffect(() => { + setWrapperVisible(visible); + }, [visible]); + + useEffect(() => { + wrapperVisible && window.addEventListener('click', clickDocumentCancel); + return () => { + window.removeEventListener('click', clickDocumentCancel); + }; + }, [wrapperVisible]); + + //禁止滚动 + useOverFlowScroll('body', wrapperVisible as boolean); + //异步关闭后重置状态 + const afterAsyncClose = () => { + setWrapperVisible(false); + isCloseWorking.current = false; + setOkLoading(false); + setCancelLoading(false); + }; + //确认 + const finish = () => { + if (!onOk) { + setWrapperVisible(false); + } + if (!isCloseWorking.current) { + isCloseWorking.current = true; + if (typeof onOk === 'function' && isPromiseFn(onOk)) { + setOkLoading(true); + onOk && + onOk() + .then(() => { + afterAsyncClose(); + }) + .catch(() => { + afterAsyncClose(); + }); + } else { + onOk && onOk(); + setWrapperVisible(false); + isCloseWorking.current = false; + } + } + } + //取消 + const cancel = () => { + if (!onCancel) { + setWrapperVisible(false); + } + if (!isCloseWorking.current) { + isCloseWorking.current = true; + if (typeof onCancel === 'function' && isPromiseFn(onCancel)) { + setCancelLoading(true); + onCancel && + onCancel() + .then(() => { + afterAsyncClose(); + }) + .catch(() => { + afterAsyncClose(); + }); + } else { + onCancel && onCancel(); + setWrapperVisible(false); + isCloseWorking.current = false; + } + } + } + const drawerContentStyle = useMemo(() => { + const size = typeof width === 'string' ? width : width + '%'; + switch (align) { + case 'right': return { + top: 0, + right: 0, + height: '100%', + width: size + } + case 'left': return { + top: 0, + left: 0, + height: '100%', + width: size + } + case 'bottom': return { + bottom: 0, + left: 0, + width: '100%', + height: size + } + case 'top': return { + top: 0, + left: 0, + width: '100%', + height: size + } + } + }, [align]) + + return ( +
+ { + e.style.display = 'block'; + }} + onExited={(e: HTMLDivElement) => { + e.style.display = 'none'; + }} + > +
+ { + e.style.display = 'flex'; + }} + onExited={(e: HTMLDivElement) => { + e.style.display = 'none'; + }} + > +
e.stopPropagation()}> +
+
+
+ {title} +
+ +
+
+
{children}
+
+ {footer || ( + <> + + + + )} +
+
+
+
+
+
+ ); +}; + + +export default Drawer; diff --git a/packages/concis-react/src/Drawer/interface.ts b/packages/concis-react/src/Drawer/interface.ts new file mode 100644 index 00000000..06b317bc --- /dev/null +++ b/packages/concis-react/src/Drawer/interface.ts @@ -0,0 +1,75 @@ +import { ReactNode, CSSProperties } from 'react'; + +interface DrawerProps { + /** + * @description 类名 + */ + className?: string; + style?: CSSProperties; + children?: ReactNode; + /** + * @description 标题 + * @default '' + */ + title?: string | ReactNode; + /** + * @description 显示状态 + * @default false + */ + visible?: boolean; + /** + * @description 出现位置 + * @default right + */ + align?: 'left' | 'right' | 'top' | 'bottom'; + /** + * @description 确认按钮props + * @default type -> primary + */ + okButtonProps?: object; + /** + * @description 取消按钮props + * @default type -> text + */ + cancelButtonProps?: object; + /** + * @description 自定义页脚 + * @default 确定、取消按钮 + */ + footer?: ReactNode; + /** + * @description 确认按钮文字 + * @default 确定 + */ + okText?: string; + /** + * @description 取消按钮文字 + * @default 取消 + */ + cancelText?: string; + /** + * @description 对话框宽度百分比 + * @default 520px + */ + width?: number | string; + /** + * @description 确认回调函数 + * @default () => + */ + onOk?: Function; + /** + * @description 取消关闭回调函数 + * @default () => + */ + onCancel?: Function; + /** + * @description 调用式函数Modal内容 + */ +} +type DialogStyle = { + width?: string; + height?: string; + opacity?: string; +}; + +export type { DrawerProps, DialogStyle }; diff --git a/packages/concis-react/src/Drawer/styles/animation.less b/packages/concis-react/src/Drawer/styles/animation.less new file mode 100644 index 00000000..bd89353a --- /dev/null +++ b/packages/concis-react/src/Drawer/styles/animation.less @@ -0,0 +1,135 @@ +.fadedrawer-enter, +.fadedrawer-appear { + opacity: 0; +} + +.fadedrawer-enter-active, +.fadedrawer-appear-active { + opacity: 1; + transition: opacity 200ms; +} + +.fadedrawer-exit { + opacity: 1; +} + +.fadedrawer-exit-active { + opacity: 0; + transition: opacity 200ms; +} + +.fadedrawer-right-content-enter, +.fadedrawer-right-content-appear { + transform: translateX(100%); +} + +.fadedrawer-right-content-enter-active, +.fadedrawer-right-content-appear-active { + transform: translateX(0); + transition: transform 300ms; +} + +.fadedrawer-right-content-exit { + transform: translateX(0); +} + +.fadedrawer-right-content-exit-active { + transform: translateX(100%); + transition: transform 300ms; +} +.fadedrawer-left-content-enter, +.fadedrawer-left-content-appear { + transform: translateX(-100%); +} + +.fadedrawer-left-content-enter-active, +.fadedrawer-left-content-appear-active { + transform: translateX(0); + transition: transform 300ms; +} + +.fadedrawer-left-content-exit { + transform: translateX(0); +} + +.fadedrawer-left-content-exit-active { + transform: translateX(-100%); + transition: transform 300ms; +} +.fadedrawer-top-content-enter, +.fadedrawer-top-content-appear { + transform: translateY(-100%); +} + +.fadedrawer-top-content-enter-active, +.fadedrawer-top-content-appear-active { + transform: translateY(0); + transition: transform 300ms; +} + +.fadedrawer-top-content-exit { + transform: translateY(0); +} + +.fadedrawer-top-content-exit-active { + transform: translateY(-100%); + transition: transform 300ms; +} +.fadedrawer-bottom-content-enter, +.fadedrawer-bottom-content-appear { + transform: translateY(100%); +} + +.fadedrawer-bottom-content-enter-active, +.fadedrawer-bottom-content-appear-active { + transform: translateY(0); + transition: transform 300ms; +} + +.fadedrawer-bottom-content-exit { + transform: translateY(0); +} + +.fadedrawer-bottom-content-exit-active { + transform: translateY(100%); + transition: transform 300ms; +} + +@media screen and (max-width: 767px) { + .concis-drawer { + &-content { + width: 90vw; + } + } + .fadeContent-enter, + .fadeContent-appear { + top: @concis-drawer-fadeExit-transform; + left: @concis-drawer-fadeExit-transform; + width: 80vw; + opacity: 0; + } + + .fadeContent-enter-active, + .fadeContent-appear-active { + top: @concis-drawer-transform; + left: @concis-drawer-transform; + width: 90vw; + opacity: 1; + transition: top 200ms, width 200ms, left 200ms, opacity 200ms; + } + + .fadeContent-exit { + top: @concis-drawer-transform; + left: @concis-drawer-transform; + width: 90vw; + opacity: 1; + } + + .fadeContent-exit-active { + top: @concis-drawer-fadeExit-transform; + left: @concis-drawer-fadeExit-transform; + width: 80vw; + opacity: 0; + transition: top 200ms, width 200ms, left 200ms, opacity 100ms; + } +} diff --git a/packages/concis-react/src/Drawer/styles/index.module.less b/packages/concis-react/src/Drawer/styles/index.module.less new file mode 100644 index 00000000..9434beb1 --- /dev/null +++ b/packages/concis-react/src/Drawer/styles/index.module.less @@ -0,0 +1,88 @@ +@import '../../styles/common.less'; +@import './animation.less'; + +@concis-drawer-light-border: #e5e6eb; +@concis-drawer-dark-border: #484849; +@concis-drawer-transform: 50%; +@concis-drawer-fadeExit-transform: 40%; + +.concis-drawer, +.concis-dark-drawer { + &-dialog { + position: fixed; + top: 0; + left: 0; + z-index: 1001; + width: 100vw; + height: 100vh; + background: rgba(29, 33, 41, 0.6); + transition: 0.1s linear; + } + &-content { + position: absolute; + z-index: 1002; + background: #ffffff; + border-radius: @concis-radius-xs; + display: flex; + flex-direction: column; + &-header { + .concis-title { + display: flex; + align-items: center; + justify-content: space-between; + padding: @concis-transform-lg; + font-weight: 500; + border-bottom: 1px solid @concis-drawer-light-border; + color: #1d2129; + .title { + span { + margin-left: @concis-transform-ms; + font-size: @concis-font-lg; + } + } + .close-icon { + font-size: @concis-font-sm; + cursor: pointer; + } + } + } + &-view { + padding: @concis-transform-lg 24px; + font-size: @concis-font-md; + border-bottom: 1px solid @concis-drawer-light-border; + color: #1d2129; + flex: 1; + } + &-footer { + width: 100%; + padding: 16px @concis-transform-lg; + text-align: right; + .button { + .concis-button-text, + .concis-button-primary { + height: 30px !important; + } + } + .cancel-btn { + margin-right: @concis-transform-ms; + } + } + } +} +.concis-dark-drawer { + &-dialog { + background: rgba(23, 23, 26, 0.6); + } + &-content { + color: #c4c4c5; + background: #2a2a2b; + &-header { + .concis-title { + border-bottom: 1px solid @concis-drawer-dark-border; + } + } + &-view { + border-bottom: 1px solid @concis-drawer-dark-border; + } + } +} diff --git a/packages/concis-react/src/Form/demos/index6.tsx b/packages/concis-react/src/Form/demos/index6.tsx index 3579cd13..3d543cf8 100644 --- a/packages/concis-react/src/Form/demos/index6.tsx +++ b/packages/concis-react/src/Form/demos/index6.tsx @@ -4,9 +4,10 @@ import Input from '../../Input'; import CheckBox from '../../CheckBox'; import Button from '../../Button'; import Select from '../../Select'; -import TimePicker from '../../DatePicker'; +import DatePicker, { RangeDatePicker, MonthPicker, YearPicker } from '../../DatePicker'; import Rate from '../../Rate'; import Tree from '../../Tree'; +import InputPro from '../../InputPro'; import Message from '../../Message'; const option = [ @@ -55,6 +56,20 @@ const treeData = [ ], }, ]; +const hobby = [ + { + label: 'JavaScript', + }, + { + label: 'TypeScript', + }, + { + label: 'VueJS', + }, + { + label: 'ReactJS', + }, +]; export default function index1() { const form = Form.useForm(); //使用Form组件回传的hooks,调用组件内链方法 @@ -87,15 +102,39 @@ export default function index1() { + + +