antd 3.0→4.0

Icon 图标

在3.x版本中,icon的使用方法是:

import { icon } from 'antd';

<icon type="search">

在4.x版本中,修改为:

import { SearchOutlined } from '@ant-design/icons';

<SearchOutLined />

在3.x版本中,button内嵌icon的方法是:

<Button type="primary" icon={search}>

在4.x修改为:

<Button type="primary" icon={<SearchOutlined />}>搜索</Button>

<Button type="primary" shape="circle"><SearchOutlined />搜索</Button>

两者的区别在于,后者可以指定icon的位置。

Form 表单

参考antd form-从v3到v4

在3.x版本中,form的使用方法是:

import { Form } from 'antd';

const { getFieldDecorator } = form;

// 调用方法
Form.setFieldsValue({...});

return <Form>
    <FormItem {...formItemLayout} label="新增成员">
        {getFieldDecorator('members', 
          { 
            rules: [{ required: true, message: '成员不允许为空' }] ,
            initialValue: this.state.name
          })(
           <Input />,
          )
        }
    </FormItem>
</Form>

在4.x中,修改为:

// 在函数组件中
import { From } from 'antd';

const App = (props) => {

  const [formRef] = Form.useForm();

  // 调用方法
  formRef.setFieldsValue({...})
  
  return 
  <Form initialValues={{members:this.state.name}} form={formRef}>
      <FormItem 
        {...formItemLayout} 
        label="新增成员"
        name="mumbers"
        rules={[{ required: true, message: '成员不允许为空' }]}
      >
          <Input />
      </FormItem>
  </Form>
}

// 在类组件中
Class Index extends React.Component{
  // 按照eslint规则,formRef的声明需要在constructor之前
  formRef = Form.useForm();
  
  // 调用方法
  formRef.current.setFieldsValue({...})
  
  return 
  <Form initialValues={{members:this.state.name}} ref={this.formRef}>
      <FormItem 
        {...formItemLayout} 
        label="新增成员"
        name="mumbers"
        rules={[{ required: true, message: '成员不允许为空' }]}
      >
          <Input />
      </FormItem>
  </Form>
}

FormItem.name表单项名称

一般说来,FormItem的name是这样的:

<Form initialValues={{id: 3}} ref={this.formRef} {...layout}> 
  <FormItem name="id" label="id">
    <Input />
  </FormItem>
</Form>

但是,如果有一个对象,格式如下:

info:{
    ids:[121, 122];
}

表单项对应的name是info.ids[0]、info.ids[1],那它的写法——

在3.x中:

<Form initialValues={info} ref={this.formRef} {...layout}> 
  <Form.Item label="id0">
    {getFieldDecorator('info.id[0]', {
      initialValue:info.ids[0],
    })(<Input />)}
  </Form.Item>
  <Form.Item label="id1">
    {getFieldDecorator('info.id[1]', {
      initialValue:info.ids[1],
    })(<Input />)}
  </Form.Item>
</Form>

在4.x中:

<Form initialValues={info} ref={this.formRef} {...layout}> 
  <FormItem name={["info","ids",0]} label="id0">
    <Input />
  </FormItem>
  <FormItem name={["info","ids",1]} label="id1">
    <Input />
  </FormItem>
</Form>

3.x和4.x的基本区别:

版本 3.x 4.x
创建form 直接从antd引入 useForm或createRef
创建FormItem getFieldDecorator 不用
初始值initValues 在创建函数中 在Form中
校验规则rules 在创建函数中 在FormItem中
表单名name 作为创建函数的第一个参数 在FormItem中

两种方式构建组件时表单的区别:

构建方式 函数
获取引用 const formRef = Form.useForm()
其中Form是antd的对象
formRef=React.createRef()
必须写在class内部
Form属性 <Form <span style="color:red">form</span>={formRef}></Form> <Form <span style="color:red">ref</span>={formRef}></Form>
调用方法 formRef.getfieldsValue() formRef.<span style="color:red">current</span>.getfieldsValue()

校验

在3.x版本中:

  validateName = (rule, value, callback) => {
    if (!value) return callback('模块名称不能为空!');
    this.props.form.setFieldsValue({ name: value.substr(0, 30) });
    callback();
  }
  
  <FormItem label="模块名称" required {...formItemLayout}>
    {getFieldDecorator('name', { 
      rules: [{ validator: this.validateName }],
    })(
      <Input />,
    )}
  </FormItem>

4.x修改为:

  validateName = (rule, value) => {
    if (!value) return Promise.reject('模块名称不能为空!');
    this.props.form.setFieldsValue({ name: value.substr(0, 30) });
    Promise.resolve();
  }
  
  <FormItem 
    label="模块名称" 
    required 
    {...formItemLayout} 
    rules=[{ validator: this.validateName }]}
  >
    <Input />
  </FormItem>

主要修改就就是去除了校验函数中的callback,换成了Promise

4.x中的报错:
<div style="color:#ff5858;background-color:#fff0f0;padding:20px">[antd: Form.Item] children is array of render props cannot have name.</div>

错误代码:

  <FormItem 
    label="模块名称" 
    {...formItemLayout} 
    required 
    name="name"
    rules={[{ validator: this.validateName }]}
  >
      <Input
        placeholder="请输入模块名称"
        onBlur={this.onBlur}
        onChange={this.onNameChange}
      />
    {nameError && <div style={{ color: 'red' }}>{errMsg}</div>}
  </FormItem>

出错原因:

在新版本的antd中,要求FormItem有且只能有一个表单元素作为直接子元素,否则除了会报错之外,还会在表单提交时出现无法获取对应的值的问题。

修改:

  <FormItem label="模块名称" required {...formItemLayout}>
    <FormItem name="name" noStyle rules={[{ validator: this.validateName }]}>
      <Input
        placeholder="请输入模块名称"
        onBlur={this.onBlur}
        onChange={this.onNameChange}
      />
    </FormItem>
    {nameError && <div style={{ color: 'red' }}>{errMsg}</div>}
  </FormItem>

其中,为被包裹的FormItem添加noStyle属性以避免其干扰原样式。

请注意各属性的位置。

关于select.filterOption

在3.x :

<Select
  filterOptions = {
      (input, option) => {
          return option.props.children.toLowerCase().indexOf(input.toLowerCase()) > 1;
      }
  }
>
  <Option name="name" value={value} key={key}>
    {children}
  <Option>
</Select>

在4.x,不再需要props:

<Select
  filterOptions = {
      (input, option) => {
          return option.children.toLowerCase().indexOf(input.toLowerCase()) > 1;
      }
  }
>
  <Option name="name" value={value} key={key}>
    {children}
  <Option>
</Select>

option/option.children的组成如下:

interface Option{
    value: string|number;
    key: string|number;
    name?: string|number;
    children: string
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容