From 727e52c0aa10c2d5d12b49f788aa36d45b9a9370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E5=B8=A6=E5=A4=A7=E4=BD=AC=E6=B0=94=E5=9C=BA?= <188633308@qq.com> Date: Mon, 21 Jun 2021 17:18:56 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E8=A1=A8=E5=8D=95=E7=A7=8D=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-react/public/seed/form-tabs/index.jsx | 141 ++++++++++++++++ web-react/public/seed/form-tabs/tab/index.jsx | 124 ++++++++++++++ web-react/public/seed/form-tabs/tab/parts.jsx | 111 ++++++++++++ web-react/public/seed/form/index.jsx | 159 ++++++++++++++++++ web-react/public/seed/form/part.jsx | 111 ++++++++++++ 5 files changed, 646 insertions(+) create mode 100644 web-react/public/seed/form-tabs/index.jsx create mode 100644 web-react/public/seed/form-tabs/tab/index.jsx create mode 100644 web-react/public/seed/form-tabs/tab/parts.jsx create mode 100644 web-react/public/seed/form/index.jsx create mode 100644 web-react/public/seed/form/part.jsx diff --git a/web-react/public/seed/form-tabs/index.jsx b/web-react/public/seed/form-tabs/index.jsx new file mode 100644 index 0000000..eb0a9c4 --- /dev/null +++ b/web-react/public/seed/form-tabs/index.jsx @@ -0,0 +1,141 @@ +import React, { Component } from 'react' +import { Button, Tabs } from 'antd' +import { ComponentDynamic, Container } from 'components' +import { isEqual } from 'lodash' + +const tabs = [ + { + title: '标题', + component: () => import('./tab'), + show: true, + }, +] + +export default class index extends Component { + state = { + actived: '0', + loading: true, + record: null, + saving: false, + } + + // 子表单实例集合 + children = [] + + // 整合提交数据 + formData = {} + + /** + * 阻止外部组件引发的渲染,提升性能 + * 可自行添加渲染条件 + * [必要] + * @param {*} props + * @param {*} state + * @returns + */ + shouldComponentUpdate(props, state) { + return !isEqual(this.state, state) + } + + /** + * DOM加载完成钩子,可在此获取详细数据赋值到record + */ + componentDidMount() {} + + async onSubmit() { + for (const child of this.children) { + try { + const data = await child.getData() + this.formData = { + ...this.formData, + ...data, + } + } catch (e) { + return e + } + } + + //#region 提交数据 + this.setState({ saving: true }) + this.setState({ saving: false }) + //#endregion + } + + render() { + const { actived, loading, record, saving } = this.state + + return ( +
+
+ {/* 底部工具栏(需放在前面) */} +
+ +
+ + + + + +
+
+
+ {/* 顶部信息栏,不需要时刻删除 */} +
+
+ { + this.setState({ actived: activeKey }) + }} + > + {tabs.map( + (tab, i) => + tab.show && ( + + ) + )} + +
+ {tabs.map((tab, i) => { + if (tab.show) { + return ( +
+ this.children.push(c)} + /> +
+ ) + } + return <> + })} +
+
+
+
+ ) + } +} diff --git a/web-react/public/seed/form-tabs/tab/index.jsx b/web-react/public/seed/form-tabs/tab/index.jsx new file mode 100644 index 0000000..ee18b7a --- /dev/null +++ b/web-react/public/seed/form-tabs/tab/index.jsx @@ -0,0 +1,124 @@ +import React, { Component } from 'react' +import ReactDOM from 'react-dom' +import { Anchor, Card, Col, Row, Spin } from 'antd' +import { AntIcon, ComponentDynamic, Container } from 'components' +import { isEqual } from 'lodash' + +const parts = [ + { + // title: '标题', + component: () => import('./part'), + }, +] + +export default class index extends Component { + // 子表单实例集合 + children = [] + + // 整合提交数据 + formData = {} + + // 锚点挂载DOM + container = window + + /** + * 阻止外部组件引发的渲染,提升性能 + * 可自行添加渲染条件 + * [必要] + * @param {*} props + * @param {*} state + * @returns + */ + shouldComponentUpdate(props, state) { + return !isEqual(this.state, state) || this.props.loading !== props.loading + } + + /** + * DDOM加载完成钩子,在此将自身传递给父级 + */ + componentDidMount() { + if (this.props.onRef) { + this.props.onRef(this) + } + } + + /** + * 从下级组件获取表单数据,并传递给更上级组件 + * [异步,必要] + * @returns + */ + async getData() { + for (const child of this.children) { + const data = await child.getData() + this.formData = { + ...this.formData, + ...data, + } + } + return this.formData + } + + /** + * 设置锚点容器 + * [非必要] + * @param {*} container + */ + setContainer(container) { + this.container = (ReactDOM.findDOMNode(container) || {}).parentNode + } + + /** + * 渲染 + * 当前渲染结构已完善,非必要可以不用修改 + * [必要] + * @returns + */ + render() { + const { id, loading } = this.props + + return ( + this.setContainer(e)}> + + +
+
+ + {parts.map((item, i) => ( +
+ {item.title &&
{parts.title}
} + } + wrapperClassName="h-400-min" + > + {!loading && ( + this.children.push(r)} + /> + )} + +
+ ))} +
+ + {/* 锚点,如果不需要可以删除以下节点 */} + + this.container} + offsetTop={24} + targetOffset={100} + wrapperStyle={{ backgroundColor: 'transparent' }} + onClick={e => e.preventDefault()} + > + {parts.map((part, i) => ( + + ))} + + + + + ) + } +} diff --git a/web-react/public/seed/form-tabs/tab/parts.jsx b/web-react/public/seed/form-tabs/tab/parts.jsx new file mode 100644 index 0000000..0785128 --- /dev/null +++ b/web-react/public/seed/form-tabs/tab/parts.jsx @@ -0,0 +1,111 @@ +import React, { Component } from 'react' +import { Form, Spin } from 'antd' +import { AntIcon } from 'components' +import { cloneDeep, isEqual } from 'lodash' + +const initialValues = {} + +const layout = { + labelCol: { flex: '150px' }, + wrapperCol: { flex: '1' }, +} + +export default class part extends Component { + state = { + loading: true, + codes: {}, + options: {}, + } + + // 表单实例 + form = React.createRef() + + // 初始化数据 + record = {} + + /** + * 阻止外部组件引发的渲染,提升性能 + * 可自行添加渲染条件 + * [必要] + * @param {*} props + * @param {*} state + * @returns + */ + shouldComponentUpdate(props, state) { + return !isEqual(this.state, state) + } + + /** + * DOM加载完成钩子,在此将自身传递给父级,并且绑定数据 + */ + componentDidMount() { + if (this.props.onRef) { + this.props.onRef(this) + } + this.fillData({ + record: this.props.record, + }) + } + + /** + * 填充数据 + * 可以在设置this.record之后对其作出数据结构调整 + * [异步,必要] + * @param {*} params + */ + async fillData(params) { + this.record = cloneDeep(params.record) + //#region 从后端转换成前段所需格式 + //#endregion + this.form.current.setFieldsValue(this.record) + + this.setState({ + loading: false, + }) + } + + /** + * 获取数据 + * 可以对postData进行数据结构调整 + * [异步,必要] + * @returns + */ + async getData() { + const form = this.form.current + + const valid = await form.validateFields() + if (valid) { + const postData = form.getFieldsValue() + //#region 从前段转换后端所需格式 + //#endregion + return postData + } + } + + //#region 自定义方法 + /** + * 表单change事件处理,包括了所有字段的change + * [异步,非必要] + * @param {*} changedValues + * @param {*} allValues + */ + async onValuesChange(changedValues, allValues) {} + //#endregion + + render() { + const { loading } = this.state + + return ( + }> +
+ this.onValuesChange(changedValues, allValues) + } + >
+
+ ) + } +} diff --git a/web-react/public/seed/form/index.jsx b/web-react/public/seed/form/index.jsx new file mode 100644 index 0000000..c2d80e4 --- /dev/null +++ b/web-react/public/seed/form/index.jsx @@ -0,0 +1,159 @@ +import React, { Component } from 'react' +import ReactDOM from 'react-dom' +import { Anchor, Button, Card, Col, Row, Spin } from 'antd' +import { AntIcon, ComponentDynamic, Container } from 'components' +import { isEqual } from 'lodash' + +const parts = [ + { + // title: '标题', + component: () => import('./part'), + }, +] + +export default class index extends Component { + state = { + loading: true, + record: null, + saving: false, + } + + // 子表单实例集合 + children = [] + + // 整合提交数据 + formData = {} + + // 锚点挂载DOM + container = window + + /** + * 阻止外部组件引发的渲染,提升性能 + * 可自行添加渲染条件 + * [必要] + * @param {*} props + * @param {*} state + * @returns + */ + shouldComponentUpdate(props, state) { + return !isEqual(this.state, state) + } + + /** + * DOM加载完成钩子,可在此获取详细数据赋值到record + */ + componentDidMount() {} + + /** + * 提交 + * [异步,必要] + * @returns + */ + async onSubmit() { + for (const child of this.children) { + try { + const data = await child.getData() + this.formData = { + ...this.formData, + ...data, + } + } catch (e) { + return e + } + } + + //#region 提交数据 + this.setState({ saving: true }) + this.setState({ saving: false }) + //#endregion + } + + /** + * 设置锚点容器 + * [非必要] + * @param {*} container + */ + setContainer(container) { + this.container = (ReactDOM.findDOMNode(container) || {}).parentNode + } + + /** + * 渲染 + * 当前渲染结构已完善,非必要可以不用修改 + * [必要] + * @returns + */ + render() { + const { id } = this.props + + const { loading, record, saving } = this.state + + return ( +
+ this.setContainer(e)}> + + +
+
+ + {parts.map((item, i) => ( +
+ {item.title &&
{parts.title}
} + } + wrapperClassName="h-400-min" + > + {!loading && ( + this.children.push(r)} + /> + )} + +
+ ))} +
+ + {/* 锚点,如果不需要可以删除以下节点 */} + + this.container} + offsetTop={24} + targetOffset={100} + wrapperStyle={{ backgroundColor: 'transparent' }} + onClick={e => e.preventDefault()} + > + {parts.map((part, i) => ( + + ))} + + + + +
+ +
+ + + + + +
+
+
+
+ ) + } +} diff --git a/web-react/public/seed/form/part.jsx b/web-react/public/seed/form/part.jsx new file mode 100644 index 0000000..0785128 --- /dev/null +++ b/web-react/public/seed/form/part.jsx @@ -0,0 +1,111 @@ +import React, { Component } from 'react' +import { Form, Spin } from 'antd' +import { AntIcon } from 'components' +import { cloneDeep, isEqual } from 'lodash' + +const initialValues = {} + +const layout = { + labelCol: { flex: '150px' }, + wrapperCol: { flex: '1' }, +} + +export default class part extends Component { + state = { + loading: true, + codes: {}, + options: {}, + } + + // 表单实例 + form = React.createRef() + + // 初始化数据 + record = {} + + /** + * 阻止外部组件引发的渲染,提升性能 + * 可自行添加渲染条件 + * [必要] + * @param {*} props + * @param {*} state + * @returns + */ + shouldComponentUpdate(props, state) { + return !isEqual(this.state, state) + } + + /** + * DOM加载完成钩子,在此将自身传递给父级,并且绑定数据 + */ + componentDidMount() { + if (this.props.onRef) { + this.props.onRef(this) + } + this.fillData({ + record: this.props.record, + }) + } + + /** + * 填充数据 + * 可以在设置this.record之后对其作出数据结构调整 + * [异步,必要] + * @param {*} params + */ + async fillData(params) { + this.record = cloneDeep(params.record) + //#region 从后端转换成前段所需格式 + //#endregion + this.form.current.setFieldsValue(this.record) + + this.setState({ + loading: false, + }) + } + + /** + * 获取数据 + * 可以对postData进行数据结构调整 + * [异步,必要] + * @returns + */ + async getData() { + const form = this.form.current + + const valid = await form.validateFields() + if (valid) { + const postData = form.getFieldsValue() + //#region 从前段转换后端所需格式 + //#endregion + return postData + } + } + + //#region 自定义方法 + /** + * 表单change事件处理,包括了所有字段的change + * [异步,非必要] + * @param {*} changedValues + * @param {*} allValues + */ + async onValuesChange(changedValues, allValues) {} + //#endregion + + render() { + const { loading } = this.state + + return ( + }> +
+ this.onValuesChange(changedValues, allValues) + } + >
+
+ ) + } +}