React+Antd Form控件前后加文案或样式后不能获取到值问题+手写校验输入字符(包含中文)长度

问题一:控件前后加元素获取值

引入

当使用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 只作为布局作用。
在这里插入图片描述

扫描二维码关注公众号,回复: 15066306 查看本文章

问题二:手写校验

要求输入的字符不能超过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()
                },
              },
]}

猜你喜欢

转载自blog.csdn.net/qq_29493173/article/details/124859248
今日推荐