您好,登錄后才能下訂單哦!
今天小編給大家分享一下antd form表單怎么處理自定義組件的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
使用 antd 中的 Form 組件時(shí),若使用自定義組件時(shí),保存的時(shí)候獲取不到自定義組件中的值。
被設(shè)置了 name 屬性的 Form.Item 包裝的控件,表單控件會(huì)自動(dòng)添加 value(或 valuePropName 指定的其他屬性) onChange(或 trigger 指定的其他屬性)
我們可以通過表單控件自動(dòng)添加的onChage,來做數(shù)據(jù)收集同步。
父組件:
import React, { Fragment, useState, useEffect, forwardRef, useRef } from 'react'; import HeaderTable from './headerTable'; const BasicForm = forwardRef((props, ref) => { const { record } = props; const [ form ] = Form.useForm(); <Form name="taskForm" ref={ref} form={form} > <Row gutter={20}> <Col span={24}> <Form.Item name="headers" label={'Header'}> <HeaderTable ref={headerTableRef} record={record} /> </Form.Item> </Col> </Row> </Form> export default BasicForm;
子組件:
import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef} from 'react'; import { Transfer, Divider, Table, Button, Input, message, Select } from 'antd'; import AddRowTable from '@components/AddRowTable';//Table組件 const { Option } = Select; const DATATYPE = [ { id: 1, name: 'int' }, { id: 2, name: 'varchar' } ] const HeaderTable = ( props, ref ) => { const { record, isLook, onChange } = props; const addRowTable = useRef(); const [ sourceData, setSourceData ] = useState([]); const [ columns, setColumns ] = useState([]); const [ targetKeys, setTargetKeys ] = useState([]); const [ headerList, setHeaderList ] = useState([]); useEffect(() => { if (record && record.id) {//當(dāng)編輯時(shí)將傳來的數(shù)據(jù)賦值 setHeaderList(record.sourceInfoMap.headers) } }, [record]) //設(shè)置columns表頭 useEffect(() => { const columns = [ { title: '參數(shù)名稱', dataIndex: 'name', render: (text, record) => { return ( <Input value={text} onChange={tableItemChange.bind(this, record, 'name')} /> ); } }, { title: '操作', dataIndex: 'operation', align: 'center', render: (text, record, index) => { return ( <a onClick={delHandle.bind(this, record, index)}>'Delete'</a> ); } }]; setColumns(columns); },[]) // 添加一行 const handleAddTableRow = () => { setHeaderList(headerList => [...headerList, {}]); onChange(headerList => [...headerList, {}]) }; // 刪除一行 const delHandle = (record, index) => { setHeaderList(headerList => { headerList.splice(index, 1); onChange(headerList) return [...headerList]; }); }; // 表格中數(shù)據(jù)更改 const tableItemChange = (data, keyField, evt) => { const value = evt.target ? evt.target.value : evt; data[keyField] = value; onChange(headerList) }; return <div> <AddRowTable ref={addRowTable} dataSource={headerList} columns={columns} isCanAdd={isLook} disabled={isLook} addItem={handleAddTableRow.bind(this)} /> </div> } export default HeaderTable;
以上操作就可以在表單中使用自定義組件,表單也能統(tǒng)一獲取值。
不僅僅input輸入框可以這么操作,所有組件,只要你拿到值后,把值給 onChange 方法,都是可以統(tǒng)一獲取值的。
當(dāng)某些自定義的組合類組件,也希望能進(jìn)行表單元素的校驗(yàn),以及利用antd的form表單實(shí)例進(jìn)行數(shù)據(jù)的修改或者數(shù)據(jù)獲取,這招便可以派上用場啦~
<Form.Item label="周期" labelAlign="right"> {getFieldDecorator('cycle', { rules: [{ required: true, validator: checkCycle }], initialValue: cycle, })(<CycleInput cycleOptions={cycleOptions} />)} </Form.Item>
表單部分可以引入自定義的校驗(yàn)邏輯,如上面的checkCycle :
可以像下面這樣,通過Promise.reject()返回錯(cuò)誤校驗(yàn)提示,通過Promise.resolve()正確通過校驗(yàn)。
/** 校驗(yàn)生命周期輸入內(nèi)容 */ const checkCycle = useCallback((_, value) => { const format = value?.split(' '); if (!format) return Promise.reject(new Error('周期不可為空!')); /** always 永久保存選項(xiàng) */ if (format.length < 2 && format[0] === 'always') { return Promise.resolve(); } if (format[1] === 'undefined') { return Promise.reject(new Error('請(qǐng)選擇周期!')); } const num = +format[0]; if (num > 0 && format[1]) { return Promise.resolve(); } return Promise.reject(new Error('請(qǐng)輸入大于 0 的數(shù)字!')); }, []);
有關(guān)校驗(yàn)的內(nèi)容,antd也是參考一個(gè)成熟的庫 async-validator,上面這種寫法可以參考文檔這塊 asyncValidator
如果懶得看文檔直接看圖:
大概意思就是說,可以通過兩種方式來實(shí)現(xiàn)一些異步校驗(yàn):
(1)可以通過調(diào)用callback,即asyncValidator的第三個(gè)參數(shù),來完成校驗(yàn)
(2)可以通過返回Promise,來完成校驗(yàn)
注意value是該表單域的值,onChange是對(duì)應(yīng)可以改變?cè)摫韱斡虻闹档姆椒?/p>
const CycleInput = ({ value, onChange, cycleOptions }) => { const format = value?.split?.(' '); const num = format?.[0]; const type = format?.[1]; const triggerChange = changedValue => { onChange && onChange(changedValue); }; /** 根據(jù)后端接口返回的數(shù)據(jù),type 有值,則為 day、week、month、year 其一 */ /** type 若為 undefined,則 num 為 always */ const [cycleOption, setCycleOption] = useState(type ?? num); const [cycleInputValue, setCycleInputValue] = useState( (typeof +num === 'number' && !_.isNaN(+num) && num) || '', ); const onCycleChange = cycleOption => { setCycleOption(cycleOption); triggerChange( cycleOption === 'always' ? cycleOption : `${cycleInputValue} ${cycleOption}`, ); }; const onInputChange = e => { const newNumber = parseInt(e.target.value || '0', 10); if (_.isNaN(newNumber)) { return; } setCycleInputValue(newNumber); triggerChange( cycleOption === 'always' ? cycleOption : `${newNumber} ${cycleOption}`, ); }; return ( <Input.Group> {cycleOption === 'always' ? ( <Select onChange={onCycleChange } defaultValue={cycleOption} style={{ width: 240 }} > {cycleOptions.map(item => ( <Select.Option key={item.value} value={item.value}> {item.label} </Select.Option> ))} </Select> ) : ( <span> <Input value={cycleInputValue} style={{ width: 156 }} onChange={onInputChange} /> <Select onChange={onCycleChange} defaultValue={cycleOption} style={{ width: 84 }} > {cycleOptions.map(item => ( <Select.Option key={item.value} value={item.value}> {item.label} </Select.Option> ))} </Select> </span> )} </Input.Group> ); };
可以看出,自定義部分邏輯也比較簡單,通過value參數(shù)可以展示組件的值,通過onChange方法,可以改變表單域的值,實(shí)現(xiàn)了表單帶給我們的便捷功能。
以上就是“antd form表單怎么處理自定義組件”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。