美文网首页
antd 3.0→4.0

antd 3.0→4.0

作者: 之幸甘木 | 来源:发表于2021-01-08 17:02 被阅读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
    }
    

    相关文章

      网友评论

          本文标题:antd 3.0→4.0

          本文链接:https://www.haomeiwen.com/subject/ttpfaktx.html