• 第六课之antd以及组件开发介绍


    ant design的介绍

    antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。

    特性

    • 提炼自企业级中后台产品的交互语言和视觉风格。
    • 开箱即用的高质量 React 组件。
    • 使用 TypeScript 开发,提供完整的类型定义文件。
    • 全链路开发和设计工具体系。
    • 数十个国际化语言支持。
    • 深入每个细节的主题定制能力。
    // 安装antd 3.11.0,antd目前最新版本是4版本以后,目前我们项目还不能进行升级
    npm install antd@3.11.0 --save
    

    文档

    目前我们项目只能使用ant design3.x.x版本点击这里,现在最新的4版本在我们项目里不能使用

    开发页面方式的介绍

    初期

    • 第一步:打开antd的官方文档3.x.x版本
    • 第二步:查找想要使用的组件
    • 第三步:查看代码演示,看哪个代码演示的地方是符合我们原型图需要的组件
    • 第四步:查看API(最下面)和使用方式以及复制功能组件的代码,粘贴到项目里,修改数据源以及事件进行开发

    后续就进行项目里组件的复制粘贴就可以进行开发

    • 引用Button
    import { Button } from 'antd';
    
    ReactDOM.render(
      <div>
        <Button type="primary">Primary</Button>
        <Button>Default</Button>
        <Button type="dashed">Dashed</Button>
        <Button type="danger">Danger</Button>
        <Button type="link">Link</Button>
      </div>,
      mountNode,
    );
    
    • 引用CheckBox
    import { Checkbox, Row, Col } from 'antd';
    
    function onChange(checkedValues) {
      console.log('checked = ', checkedValues);
    }
    
    ReactDOM.render(
      <Checkbox.Group style={{  '100%' }} onChange={onChange}>
        <Row>
          <Col span={8}>
            <Checkbox value="A">A</Checkbox>
          </Col>
          <Col span={8}>
            <Checkbox value="B">B</Checkbox>
          </Col>
          <Col span={8}>
            <Checkbox value="C">C</Checkbox>
          </Col>
          <Col span={8}>
            <Checkbox value="D">D</Checkbox>
          </Col>
          <Col span={8}>
            <Checkbox value="E">E</Checkbox>
          </Col>
        </Row>
      </Checkbox.Group>,
      mountNode,
    );
    
    • 引用Radio
    import { Radio } from 'antd';
    
    class App extends React.Component {
      state = {
        value: 1,
      };
    
      onChange = e => {
        console.log('radio checked', e.target.value);
        this.setState({
          value: e.target.value,
        });
      };
    
      render() {
        return (
          <Radio.Group onChange={this.onChange} value={this.state.value}>
            <Radio value={1}>A</Radio>
            <Radio value={2}>B</Radio>
            <Radio value={3}>C</Radio>
            <Radio value={4}>D</Radio>
          </Radio.Group>
        );
      }
    }
    
    ReactDOM.render(<App />, mountNode);
    
    • 流程如图

    中期

    使用代码片段将可以公用的组件或者代码块提取到我们的代码片段,根据业务逻辑使用快捷命令生成代码片段,不再需要使用antd复制粘贴组件

    后期

    第一种:

    • 1.将页面所有公用功能抽离出一个公共的页面组件
    • 2.别的页面继承这个页面,然后在新增自己需要的功能

    优点:优点:页面代码量小,公用的地方走同一个文件,如果突然需要调整每个页面的同样组件的功能,会非常简单,修改移除即可

    缺点:对代码兼容性要求更高,对组件开发实力以及规划能力有较高要求

    第二种:

    • 使用vscode插件或者npm库一键生成我们页面需要的基础公用代码,写入到项目里,我们再在这个基础上进行修改
    • 配合我们成型的代码片段,快速开发

    优点:每个页面就是一个纯新的页面,只是帮助你快速生成了公用代码,开发者想如何进行开发修改都可以,你想怎么改都可以,灵活性很强

    缺点:调整公用地方就会相对麻烦,和平常开发页面没有区别

    组件开发方式

    • 第一步:在component文件夹新建一个页面组件,除了组件其余命名统一小驼峰,里面包括组件js(大驼峰)、less、imgs、入口文件index.js(方便使用)
    • 第二步:查看原型图,复制类似页面代码到当前页面js,或者通过代码片段生成、vscode插件生成相应代码
    • 第三步:修修改改开发

    组件开发步骤

    1.定义组件

    // 定义
    class GetList extends React.Component {
         render() {
             return ()
         }
    };
    // 导出
    export default GetList;
    

    2.添加construcor

    • 接收props
    • 定义state或者接收props
    • 可以定义事件名称
     constructor(props) {
          super(props);
          this.state = {
             // 查询组件配置项
             searchConfig: [{
                label: '订单编号',
                type: 'Input',
                name: 'OrderId',
                placeholder: '请输入订单编号',
             },
             ],
             // 提交参数
             postData: {
                pageIndex: 1,
                pageSize: 10,
             },
             // 弹窗是否展示
             showModal: false
          }
       }
    

    3.添加生命周期

    • 页面加载调用接口
    • 接口返回数据更新页面
    // 调用接口
    componentDidMount() {
       this.getData();
    }
    // 根据返回值进行页面的更新
    componentWillReceiveProps(nextProps) {
       const { getListListResult } = nextProps.getList;
       if (getListListResult !== this.props.getList.getListListResult) {
          const { code, data } = getListListResult;
          if (code === '0') {
             return this.setState({
                tableData: data.list,
                total: data.total
             });
          }
          message.error(getListListResult.message);
       }
    }
    

    4.添加事件

    • 按钮操作
    • 公用方法
    //查询列表
    search = (err, value) => {
       const { postData } = this.state;
       postData.pageIndex = 1;
       this.setState({
          postData: { ...postData, ...value }
       }, () => {
          this.getData();
       })
    }
    

    5.编写render里面的代码

    • 面包屑组件
    • 查询组件
    • 操作栏
    • 表格
    • 弹窗
    // 代码示例
    <div>
       {/*面包屑*/}
       <TopNav />
       {/*loading*/}
       <Spin spinning={!!this.props.loading.models.getList}>
          {/*样式common-page-content用来给当前页面间距*/}
          <div className='common-page-content'>
             {/*查询组件*/}
             <SearchForm
                onRef={r => this.child = r}
                searchConfig={searchConfig}
                search={this.search}
                key={1}
                toggleSearchForm={this.showmorecallback}
             />
             {/*操作栏*/}
             {btnArr.find(v => v.enCode === 'lr-add') && <div className='table-control-bar'>
                <Button onClick={() => this.addGetList('showModal', true)} type='primary' >新增消息模板</Button>
             </div>}
             {/*表格*/}
             <Table className='bannertable'
                rowSelection={rowSelection}
                pagination={pagination} rowKey='id'
                columns={tableColums}
                dataSource={tableData} />
          </div>
       </Spin>
       {/*弹窗*/}
       {showModal && <ShowModal hideFildModel={this.addGetList} />}
    </div>
    

    新增编辑页

    • 新增编辑的Form表单
    // 使用form组件
    <Form>
        <FormItem {...formItemLayout2} label='活动名称'>
            {getFieldDecorator('quota0', {
                initialValue: '', // 默认值
                rules: [ // 验证规则
                    { required: true, message: '请输入活动名称', },
                ]
            })(
                <Input maxLength={10} style={{  '100%' }} placeholder='字数限制10个字符' />
            )}
        </FormItem>
         <FormItem {...formTailLayout} >
             {getFieldDecorator('control', {
                 // 验证规则(必填、正则)
                 rules: [
                 ],
                 // 初始化的值
                 initialValue: ''
             })(
                 <Fragment>
                     <Button className='mar-right-width' type='primary' onClick={this.btnOk}>保存</Button>
                     <Button onClick={this.handleCancel}>取消</Button>
    
                 </Fragment>
             )}
         </FormItem>
    </Form>
    

    弹框组件Modal

    • 1.新增编辑的Form表单
    • 2.新增编辑的table表格
    <Modal
        width={500}
        title={rowInfo.Id ? '编辑' : '新增'}
        visible
        maskClosable={false}
        onCancel={this.handleClose}
        onOk={this.sureAdd}
    >
        <Form>
            <FormItem {...formItemLayout2} label='field1'>
                {getFieldDecorator('field1', {
                    initialValue: rowInfo.field1,
    
                })(
                    <Input style={{  '100%' }} placeholder='请输入Field1' maxLength={10000} />
                )}
            </FormItem>
        </Form>
    </Modal>
    
    

    组件功能图

    常用的antd组件

    通用

    • Button按钮
    • Icon图标

    布局

    Grid组件

    • Row行组件
    • Col列组件

    导航

    • Steps进度条

    数据录入

    • CheckBox多选框
    • DatePicker日期选择框
    • Form表单
    • InputNumber数字输入框
    • Radio单选框
    • Switch开关
    • Select选择器
    • TimePicker时间选择框
    • Upload上传

    数据展示

    • Popover气泡卡片
    • Tooltip文字提示
    • Tabs标签页
    • Table表格
    • Modal对话框
    • Message全局提示
    • Popconfirm气泡确认框
    • Spin加载中

    其他

    • Divider分割线

    案例

    实现内容:列表的增删查改

    • 第一步:查看ant文档并添加Form组件
    // 第一步:页面组件的新增以及完成基础的代码
    // 第二步:使用antd组件的Form组件,并使用高级搜索功能
    
    class childCom extends React.Component {
       constructor(props) {
           super(props);
           this.state = {
             ...
           };
       }
       getFields() {
            const count = this.state.expand ? 10 : 6;
            const { getFieldDecorator } = this.props.form;
            const children = [];
            for (let i = 1; i < 4; i++) {
                children.push(
                    <Col span={8} key={i} style={{ display: i < count ? 'block' : 'none' }}>
                        <Form.Item label={`Field ${i}`}>
                            {getFieldDecorator(`field${i}`, {
                            })(<Input placeholder="placeholder" />)}
                        </Form.Item>
                    </Col>,
                );
            }
            return children;
        }
    
        handleSearch = e => {
            this.props.form.validateFields((err, values) => {
                const { dataSource } = this.state;
                let field1 = values.field1;
                let field2 = values.field2;
                let field3 = values.field3;
                let searchDataSource = dataSource.filter(item => (!field1 || item.field1 == field1)
                    && (!field2 || item.field2 == field2) && (!field3 || item.field3 == field3));
                this.setState({
                    searchDataSource
                })
            });
        }
       render() {
           return (
               <Form className="ant-advanced-search-form">
                   <Row gutter={24}>{this.getFields()}</Row>
                   <Row>
                       <Col span={24} style={{ textAlign: 'right' }}>
                             <Button type="primary" onClick={this.handleSearch}>
                               Search
                 </Button>
                           <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
                               Clear
                 </Button>
                           <a style={{ marginLeft: 8, fontSize: 12 }} onClick={this.toggle}>
                               Collapse <Icon type={this.state.expand ? 'up' : 'down'} />
                           </a>
                       </Col>
                   </Row>
               </Form>
           );
       }
    }
    export default Form.create()(childCom)
    
    • 第二步:查看ant文档并添加table组件
    // 定义state,以及表格的列数据
    
       constructor(props) {
           super(props);
           this.state = {
             dataSource: []
           };
           this.columns=[];
       }
    
    // 添加Table组件,至少需要两个属性,1.列属性,2.数据源属性
    <Table columns={this.columns} dataSource={data} />
    
    • 第三步:添加中间区域的Button组件用于新增
    <Button type="primary" onClick={() => this.showModal('showModal', true)}>新增</Button>
    
    • 第四步:父组件添加新增组件弹窗ShowModal
    // 引入子组件ShowModal
    import ShowModal from './ShowModal';
    // 父组件定义state
    this.state = {
        ...
        showModal: false
    };
    // 控制弹窗的开启关闭
    showModal = (field, flag) => {
        this.setState({ [field]: flag })
    }
    // 修改render
    render(){
        const { dataSource, showModal } = this.state;
        return (
            ...
            {showModal && <ShowModal showModal={this.showModal} />}
        )
    }
    
    • 第五步:添加子组件ShowModal
    <Modal
        width={500}
        title={'添加'}
        visible
        maskClosable={false}
        onCancel={this.handleClose}
        onOk={this.sureAdd}
    >
        <Form>
             <FormItem {...formItemLayout2} label='Field1'>
                 {getFieldDecorator('Field1', {
                     initialValue: '',
            
                 })(
                     <InputNumber style={{  '100%' }} placeholder='请输入Field1' maxLength={10000} />
                 )}
             </FormItem>
        </Form>
    </Modal>
    
    • 第六步:实现新增功能
    // 父组件添加新增函数并传递到子组件
    addInfo = (obj) => {
          const { dataSource } = this.state;
          dataSource.push(obj);
          this.setState({
              dataSource
          })
    }
    
    {showModal && <ShowModal showModal={this.showModal} addInfo={this.addInfo} />}
    
    // 子组件的弹窗组件获取页面的值并调用父组件新增功能
    sureAdd = () => {
        this.props.form.validateFields((err, values) => {
            if (!err) {
                this.props.addInfo(values);
                this.handleClose();
            }
        });
    }
    
    • 第七步:实现删除功能
    // 父组件删除按钮添加确认删除功能
    <Popconfirm title={'确认删除吗'} onConfirm={() => this.deleteInfo(record)} okText="Yes" cancelText="No">
        <a >删除</a>
    </Popconfirm>
    
    // 父组件添加删除函数
    
    deleteInfo = record => {
        const { dataSource } = this.state;
        // 根据Id找到要删除的索引
        let deleteIndex = dataSource.findIndex(item => item.Id === record.Id)
        dataSource.splice(deleteIndex, 1);
        this.setState({ dataSource });
    };
    
    • 第八步:实现修改功能
    // 父组件的修改按钮传递当前数据内容到子组件
    <a onClick={() => this.showModal('showModal', true, record)}>修改</a>
    
    // 父组件showModal修改,传递当前修改的元素
    showModal = (field, flag, rowInfo) => {
       this.setState({ [field]: flag, rowInfo })
    }
    
    // 父组件添加修改函数
    editInfo = (obj) => {
        const { dataSource } = this.state;
        let index = dataSource.findIndex((item) => item.Id === obj.Id);
        dataSource[index] = obj;
        this.setState({
            dataSource
        })
    }
    
    // 父组件的子组件添加rowInfo属性和传递editInfo函数
    {showModal && <ShowModal showModal={this.showModal} addInfo={this.addInfo} rowInfo={rowInfo} editInfo={this.editInfo} />}
    
    
    // 子组件接收父组件的rowInfo的值并给到state
    constructor(props) {
        super(props);
        this.state = {
            rowInfo: props.rowInfo || {}
        };
    }
    // 子组件修改添加和修改的逻辑
    sureAdd = () => {
        this.props.form.validateFields((err, values) => {
            if (!err) {
                const { rowInfo } = this.state;
                // 如果有值说明是编辑
                if (rowInfo.Id) {
                    values.Id = rowInfo.Id;
                    this.props.editInfo(values);
                }
                // 否则是新增
                else {
                    values.Id = Math.random();
                    this.props.addInfo(values);
                }
                this.handleClose();
            }
        });
    }
    // render接收父组件的值,并修改FormItem组件的initialValue
    render() {
        const { rowInfo } = this.state;
        return(
            ...
            <FormItem {...formItemLayout2} label='field1'>
                {getFieldDecorator('field1', {
                    initialValue: rowInfo.field1,
    
                })(
                    <Input style={{  '100%' }} placeholder='请输入Field1' maxLength={10000} />
                )}
           </FormItem>
        )
    }
    
    • 第九步:实现查询功能
    // 父组件添加searchDataSource,用于查询后的searchDataSource
    this.state = {
        dataSource: [
            {
                Id: '123123',
                field1: '1',
                field2: 'John Brown',
                field3: 32,
    
            },
        ],
        searchDataSource: [
            {
                Id: '123123',
                field1: '1',
                field2: 'John Brown',
                field3: 32,
    
            },
        ],
        rowInfo: {},
        showModal: false
    };
    // 父组件修改table的数据源
    <Table columns={this.columns} dataSource={searchDataSource} />
    // 修改查询函数
    handleSearch = e => {
        this.props.form.validateFields((err, values) => {
            const { dataSource } = this.state;
            let field1 = values.field1;
            let field2 = values.field2;
            let field3 = values.field3;
            let searchDataSource = dataSource.filter(item => (!field1 || item.field1 == field1)
                && (!field2 || item.field2 == field2) && (!field3 || item.field3 == field3));
            this.setState({
                searchDataSource
            })
        });
    }
    
  • 相关阅读:
    robotframework框架
    pytest系列(四)- pytest+allure+jenkins
    robotframework框架
    接口测试时遇到 java 代码加密请求数据,用 python 的我该怎么办?
    selenium原理应用
    pytest系列(一):什么是单元测试界的高富帅?
    python appium搭建app自动化测试环境
    python selenium
    python3.4 + pycharm 环境安装 + pycharm使用
    requests(三):json请求中中文乱码处理
  • 原文地址:https://www.cnblogs.com/Hsong/p/14019440.html
Copyright © 2020-2023  润新知