一、关联表单项 - 动态增删输入框Input

      

  • 封装子组件

    class ParamsInputArray extends React.Component{
    constructor(props){
    super(props);
    } // 改变一组input输入框中的key值和value值
    handleChange = (paramType, index) => {
    const { onChange, value={} } = this.props; if(event && event.target && event.target.value){
    let newValue = {...value};
    if(paramType == 'key'){
    newValue.key = event.target.value
    }else{
    newValue.value = event.target.value
    } // 调用父级props传来的onChange事件
    // 将newValue对象存入数组对应index的位置
    onChange(newValue, index)
    }
    } render() {
    const { value={}, keys, index, add, remove} = this.props; return (
    <Row gutter={8}>
    <Col span={5}>
    <Input placeholder="颜色/尺码" defaultValue={value.key} onChange={() => this.handleChange('key', index)}/>
    </Col>
    <Col span={8}>
    <Input placeholder="请输入参数" defaultValue={value.value} onChange={() => this.handleChange('value', index)}/>
    </Col>
    <Col span={2}>
    {keys.length > 1 ? (
    <Icon
    type="minus-circle-o"
    onClick={() => remove(index)}
    />
    ) : null}
    </Col>
    <Col span={6}>
    {index === 0 ? (
    <Button type="primary" onClick={() => add()}>新增</Button>
    ) : null}
    </Col>
    </Row>
    )
    }
    }
  • 使用的几个方法

    // 初始化keys
    const initKeys = (detail) => {
    let defaultKeys = [];
    detail.param.forEach((val, index) => defaultKeys.push(index))
    return defaultKeys;
    } // 经过 getFieldDecorator 包装的控件
    // 表单控件会自动添加 value(或 valuePropName 指定的其他属性)
    // onChange(或 trigger 指定的其他属性)
    // 数据同步将被 Form 接管
    getFieldDecorator('keys', { initialValue: current && detail && detail.param.length ? initKeys(detail) : [0] }); // 获取(上面注册了的)表单控件的值
    const keys = getFieldValue('keys');
    // 增加表单项
    const add = () => {
    const keys = getFieldValue('keys'); if (keys.length === 5) {
    message.info('产品参数最多5个')
    return;
    }
    let nextKeys = keys;
    let nextKeyValue = keys[keys.length-1]+1;
    nextKeys = nextKeys.concat(nextKeyValue); setFieldsValue({
    keys: nextKeys,
    });
    }; // 删除表单项
    const remove = index => {
    const keys = getFieldValue('keys');
    let param = getFieldValue('param');
    if (keys.length === 1) {
    return;
    }
    if(param[index]){
    param.splice(index, 1)
    }
    setFieldsValue({
    keys: keys.filter((keyItem, i) => i !== index),
    param
    });
    };
    // 初始化params的初始值
    const initParamValue = (detail, index) => {
    let defaultParamValue = {};
    detail.param.forEach((p, i) => {
    if(i === index){
    defaultParamValue = p
    }
    })
    return defaultParamValue;
    } // 修改并存入 :每一组表单项key和value改变后的newValue对象
    const handleParamChange = (newValue, index) => {
    let param = getFieldValue('param');
    setFieldsValue({
    param: param.map((p, i) => i == index ? newValue : p)
    });
    } // 循环keys动态渲染出:关联输入框表单项
    const paramsFormItems = keys.map((k, index) => (
    <FormItem
    {...(index === 0 ? formLayout : formLayoutWithOutLabel)}
    label={index === 0 ? '参数信息' : ''}
    key={k}
    >
    {getFieldDecorator(`param[${index}]`, {
    validateTrigger: ['onChange', 'onBlur'],
    rules: [
    {
    type: 'object',
    required: true,
    validator: (_, value, callback) => {
    if (!value.key || !value.value || (value.key && value.key.length > 10) || (value.value && value.value.length > 20)) {
    callback('请输入1-10字参数及1-20参数信息或删除此输入框')
    } else {
    callback()
    }
    }
    },
    ],
    initialValue: current && detail && detail.param.length ? initParamValue(detail, index) : {}
    })(
    <ParamsInputArray keys={keys} index={index} add={add} remove={remove} onChange={handleParamChange}/> // 自定义的两个为一组的Input输入框组件
    )}
    </FormItem>
    ));
  • 弹框的Form表单列表中嵌入

    {paramsFormItems}

二、关联表单项 - 单独两个Input输入框

     

  • 封装子组件

    class RegionInput extends React.Component{
    constructor(props){
    super(props);
    }
    handleChange = (regionType) => {
    const { onChange, value={} } = this.props; if(event && event.target && event.target.value){
    let newValue = {...value};
    if(regionType == 'min'){
    newValue.min = Number(event.target.value)
    }else{
    newValue.max = Number(event.target.value)
    }
    onChange(newValue)
    }
    } render() {
    const { value={}, disabled } = this.props; return (
    <Row gutter={8}>
    <Col span={11}>
    <Input placeholder="最低价" defaultValue={value.min} onChange={() => this.handleChange('min')} disabled={disabled}/>
    </Col>
    <Col span={2}>
    <span style={{width: '100%', textAlign: 'center'}}>—</span>
    </Col>
    <Col span={11}>
    <Input placeholder="最高价" defaultValue={value.max} onChange={() => this.handleChange('max')} disabled={disabled}/>
    </Col>
    </Row>
    )
    }
    }
  • 表单中使用子组件

    <FormItem label="价格区间" {...formLayout}>
    {getFieldDecorator('priceRegion', {
    validateTrigger: ['onChange', 'onBlur'],
    rules: [
    {
    type: 'object',
    required: getFieldValue('basis') == 'Price',
    validator: (_, value, callback) => {
    if (getFieldValue('basis') == 'Price' && ( isNaN(value.min) || isNaN(value.max) || !(/^[0-9]+([.]\d{1,2})?$/.test(value.min)) || !(/^[0-9]+([.]\d{1,2})?$/.test(value.max)) || (value.min && value.min > 50000 ) || (value.max && value.max > 50000))) {
    callback('请输入0-50000元价格区间')
    }else{
    callback()
    }
    }
    }],
    initialValue: current && current.priceRegion ? {min: (current.priceRegion.min/100).toFixed(2), max: (current.priceRegion.max/100).toFixed(2)} : {}
    })(
    <RegionInput onChange={handleRegionChange} disabled={getFieldValue('basis') != 'Price'}/>
    )}
    </FormItem>

三、单选按钮RadioButton

  • RadioGroup包裹六个RadioButton

    <RadioGroup defaultValue='5' onChange={(e) => this.handleStatusChange(e)}>
    <RadioButton value='5'>全部</RadioButton>
    <RadioButton value='0'>未付款</RadioButton>
    <RadioButton value='1'>待收货</RadioButton>
    <RadioButton value='2'>已签收</RadioButton>
    <RadioButton value='3'>交易成功</RadioButton>
    <RadioButton value='4'>交易失败</RadioButton>
    </RadioGroup>
  • handleStatusChange改变state中存的status获取,走接口获取对应的列表数据

    handleStatusChange = e => {
    const { dispatch } = this.props;
    const { keyword, currentPage } = this.state;
    if(e && e.target && e.target.value){
    let value = e.target.value == 5 ? null : Number(e.target.value);
    this.setState({status: value})
    dispatch({
    type: 'order/fetch',
    payload: {
    currentPage,
    e: {
    status: value,
    keyword
    },
    showCount: 10
    },
    });
    }
    }

四、开关按钮Switch

 

 <FormItem label="是否设为系统产品" {...formLayout}>
{ getFieldDecorator('fromSystem', {
rules: [{ required: true, message: '请选择是否设为系统产品'}],
initialValue: current && detail ? detail.fromSystem : false
})(
<Switch defaultChecked={current && detail ? detail.fromSystem : false} />
)}
</FormItem>

五、日期选择框 - 一个带时间的日期

<FormItem label="发布时间" {...formLayout}>
{ getFieldDecorator('publishTime', {
rules: [{ type: 'object', required: true, message: '请选择发布时间' }],
initialValue: current && detail ? moment(detail.publishTime) : moment(new Date()),
})(
<DatePicker showTime format="YYYY-MM-DD HH:mm:ss" />
)}
</FormItem>

六、日期选择框 - 两个起止日期

const { RangePicker } = DatePicker;

// state中初始值
rangePicker: null, const rangeConfig = {
rules: [{ type: 'array' }],
}; <FormItem label="选择日期">
{
getFieldDecorator('rangePicker', rangeConfig)(<RangePicker style={{width: 550}} />)
}
</FormItem>

转载请注明出处

【后台管理系统】—— Ant Design Pro组件使用(二)的更多相关文章

  1. ant design pro (十二)advanced UI 测试

    一.概述 原文地址:https://pro.ant.design/docs/ui-test-cn UI 测试是项目研发流程中的重要一环,有效的测试用例可以梳理业务需求,保证研发的质量和进度,让工程师可 ...

  2. 【后台管理系统】—— Ant Design Pro组件使用(一)

    一.搜索Search      搜索框 <Search placeholder="请输入关键字" defaultValue={kw && kw != 'nul ...

  3. 和我一起,重零开始学习Ant Design Pro开发解决方案(二)部署示例项目

  4. Ant Design Pro路由传值

    Ant Design Pro 路由传值 了解Ant Design Pro组件间通讯原理的小伙伴肯定都知道,两个页面之间可以通过Models进行传值,在以往的传值过程中,我都是直接将需要的值直接一股脑的 ...

  5. 【后台管理系统】—— Ant Design Pro入门学习&项目实践笔记(三)

    前言:前一篇记录了[后台管理系统]目前进展开发中遇到的一些应用点,这一篇会梳理一些自己学习Ant Design Pro源码的功能点.附:Ant Design Pro 在线预览地址. Dashboard ...

  6. Ant Design Pro (中后台系统)教程

    一.概念:https://pro.ant.design/docs/getting-started-cn(官方网站) 1.Ant Design Pro 是什么:  https://www.cnblogs ...

  7. ant design pro 当中改变ant design 组件的样式和 数据管理

    ant design pro 简介 官网简介 链接 https://pro.ant.design/docs/getting-started-cn 项目结构 https://github.com/ant ...

  8. (二)React Ant Design Pro + .Net5 WebApi:前端环境搭建

    首先,你需要先装一个Nodejs,这是基础哦.如果没有这方面知识的小伙伴可以在园子里搜索cnpm yarn等关键字,内容繁多,此不赘述,参考链接 一. 简介 1. Ant Design Pro v5 ...

  9. ant design pro(二)布局

    一.概述 参看地址:https://pro.ant.design/docs/layout-cn 其实在上述地址ant-design上已经有详细介绍,本文知识简述概要. 页面整体布局是一个产品最外层的框 ...

随机推荐

  1. C++中函数参数的扩展

    1,C++ 可以看成是一种更好的 C 语言,所以 C++ 会考虑 C 的欠缺部分,然后给  与一些补充和扩展,本节课讲述 C++ 对函数参数的非常重要的扩展: 2,函数参数的默认值: 1,C++ 中可 ...

  2. Python 入门之格式化输出

    Python 入门之格式化输出 1.格式化 (1)%为占位 (2)%s --- 站字符串的位置(数字.字符串都能够进行填充) name = input('请输入姓名:') age = input('请 ...

  3. PythonDay06

    第六章 今日内容 小数据池 深浅拷贝 集合 小数据池 == is id == 判断两个值是否相等 is --- 是 判断两个值的内存地址是否相等 代码块:一个py文件,一个函数,一个模块,终端中每一行 ...

  4. Kotlin学习(5)类型系统

    可空性(避免空指针异常) /* *这个函数的参数代表传入一个String类型变量的实例,这代表它不可以为空 */ fun a(str:String){ println(str) } //这样调用a() ...

  5. django后台集成富文本编辑器Tinymce的使用

    富文本编辑器Tinymce是使用步骤: 1.首先去python的模块包的网站下载一个django-tinymce的包 2.下载上图的安装包,然后解压,进入文件夹,执行: (pychrm直接运行命令pi ...

  6. Python 中Semaphore 信号量对象、Event事件、Condition

    Semaphore 信号量对象 信号量是一个更高级的锁机制.信号量内部有一个计数器而不像锁对象内部有锁标识,而且只有当占用信号量的线程数超过信号量时线程才阻塞.这允许了多个线程可以同时访问相同的代码区 ...

  7. Python自动化学习--元素定位

    from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www. ...

  8. 029-实现阿里云主机VPC网络SDN结构

  9. CIC许可更新

    打开IA软件,点击软件中的[License],可以查看当前许可是否可用或者过期,如果过期,点击下方的[Load License],选择最新的I3许可文件加载,重启电脑.

  10. Java并发——原子变量和原子操作

    很多情况下我们只是需要一个简单的.高效的.线程安全的递增递减方案.注意,这里有三个条件:简单,意味着程序员尽可能少的操作底层或者实现起来要比较容易:高效意味着耗用资源要少,程序处理速度要快:线程安全也 ...