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
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容