问题一:控件前后加元素获取值
引入
当使用Form.Item时,内部包含Select选择框,但由于需求,需要在Select前加一个 “*” 样式装点。
这个时候会导致使用form的name属性时:getFieldValue('country') 无法读取到值(见下图),因为form不仅仅是只包含了Select框元素。
原代码(效果未实现):
<Form.Item label="地区" name="country" key="country">
<span className={Styles.specialrequired} style={{ transform: 'translate(-60px, 4px)'}}>
*
</span>
<Select
showSearch
style={{ width: 150 }}
dropdownMatchSelectWidth={false}
placeholder="请选择地区"
value={selectCountry}
onChange={e => setSelectCountry(e)}
>
{countryList?.map(e => (
<Select.Option
key={e.name}
value={e.value}
>
{e.name}
</Select.Option>
))}
</Select>
</Form.Item>
当地区改变时,country值一直为undefined,未获取状态。
解决方案
修改后代码:
<Form.Item label="地区">
<span className={Styles.specialrequired} style={{ transform: 'translate(-60px, 4px)'}}>
*
</span>
<Form.Item name="country" key="country" noStyle>
<Select
showSearch
style={{ width: 150 }}
dropdownMatchSelectWidth={false}
placeholder="请选择地区"
value={selectCountry}
onChange={e => setSelectCountry(e)}
>
{countryList?.map(e => (
<Select.Option
key={e.name}
value={e.value}
disabled={!_.some(region, item => item.name === e.name)}
>
{e.name}
</Select.Option>
))}
</Select>
</Form.Item>
</Form.Item>
再去看Antd官方文档解释: 如果控件前后还有一些文案或样式装点,或者一个表单项内有多个控件,应使用内嵌的 Form.Item 完成。 你可以给 Form.Item 自定义 style 进行内联布局,或者添加 noStyle 作为纯粹的无样式绑定组件
意思可以类比于div盒子,当控件中有多个控件或元素时,需要将最外层的Form.Item作为布局加上label属性,给里面的每个需要获取的控件再包裹一次Form.Item并且给上name属性.
注意,在 label 对应的 Form.Item 上不要在指定 name 属性,这个 Item 只作为布局作用。
问题二:手写校验
要求输入的字符不能超过64个字符,且不包含特殊字符。
注意是字符而不是字符串长度,所以不能使用antd自带的min和max规则判断字符串的length。
字符长度(错误):不能正确校验中文
{ type: 'string', min: 0, max: 64, message: '任务名称必须在0-64字符内!' },
对字符串进行处理,将中文处理未双字节 后再取长度进行判断
解决
在Form.item中加上rules属性,并手写校验规则,建议把所有校验规则条件写在此处,可以控制条件校验的先后顺序
此处先校验是否包含特殊字符,当不包含特殊字符时才校验任务名称的字符长度
rules={[
{
validator(_, value) {
const pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>《》/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]",
)
if (pattern.test(value)) {
return Promise.reject(new Error('任务名称不允许包含特殊字符'))
}
if (value.replace(/[\u4e00-\u9fa5]/g, 'aa').length > 64) {
return Promise.reject(new Error('任务名称不能超过64个字符'))
}
return Promise.resolve()
},
},
]}
|