第六課之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={{ width: '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={{ width: '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={{ width: '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={{ width: '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={{ width: '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
        })
    });
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM