Ant Design 學習記錄


遇到的問題: 

  •   點擊列表中的一個字段 , 顯示出一條指定id(其他篩選條件的)數據 

解決這個問題之前,要先了解 Antd的 Table中的  Column  列描述數據對象,是 columns 中的一項,Column 使用相同的 API。  官網地址

從中我們可以知道 :  render  生成復雜數據的渲染函數,參數分別為(當前行的值,當前行數據,行索引),@return 里面可以設置表格行/列合並 類型是函數 (text, record, index) => { }  

 

 

 

 

 

 

 點擊后彈出以下列表

解決:

兩種寫法 :

  1. 直接給子組件傳 props值, 然后子組件渲染this.props.item
  2. 給子組件傳id值,然后子組件通過URL傳給后台,后台篩選出滿足條件的數據。
  1 import React, {Component} from 'react';
  2 import { PageHeader, Table, Input, Card } from "antd";
  3 import HttpUtils from "../../utils/HttpUtils";
  4 import moment from "moment";
  5 import FilterForm from "../../components/Filter";
  6 import Team from './StatisticalTeam';
  7 import Share from './StatisticalShare';
  8 import User from './StatisticalUser';
  9 
 10 const {TextArea} = Input;
 11 const select = [
 12     {
 13         name: '時間',
 14         type: 'date',
 15         dataIndex: ['start_time', 'end_time'],
 16         // wrap: 24
 17     }
 18 ]
 19 
 20 export default class Hello extends Component {
 21     constructor(props) {
 22         super(props);
 23         this.state = {
 24             form: {
 25                 pers: 10,
 26                 page: 1
 27             },
 28             loading:false,
 29             values: {},
 30             dataSource: [],
 31             value: '',
 32             count: ''
 33         };
 34         this.columns = [
 35             {   
 36                 width:400,
 37                 title: '記錄創造時間',
 38                 dataIndex: 'first_day',
 39                 key: 'first_day',
 40                 render: (props) => {
 41                     // return this.timestampToTime(props);
 42                     const  time =  this.timestampToTime(props);
 43                    return moment(time).format('YYYY-MM-DD hh:mm:ss')
 44                 }
 45             },
 46             {
 47                 title: '分享',
 48                 dataIndex: 'share_award_real_amount',
 49                 key: 'share_award_real_amount',
 50                 render: (text, record) => {
 51                     return (
 52                         <div
 53                         onClick={() => {
 54                             this.setState({
 55                                 visible_pwd: true,
 56                                 user_id: record.id
 57                             })
 58                         }}
 59                         
 60                         style={{marginRight: 10, cursor: "pointer", color: '#40a9ff'}}
 61                         >
 62                               <Share item={record} loadUserList={()=> {
 63                                 this._loadUserList()
 64                             }}/>    
 65                     </div>
 66                     )
 67                 }
 68             }, {
 69                 title: '團隊',
 70                 // dataIndex: 'share_award_real_amount',
 71                 // key: 'share_award_real_amount',
 72                 render: (text, record) => {
 73                     return (
 74                         <div
 75                         onClick={() => {
 76                             this.setState({
 77                                 visible_pwd: true,
 78                                 user_id: record.id
 79                             })
 80                         }}
 81                         
 82                         style={{marginRight: 10, cursor: "pointer", color: '#40a9ff'}}
 83                         >
 84                             <Team item={record} loadUserList={()=> {
 85                                 this._loadUserList()
 86                             }}/>           
 87                     </div>
 88                     )
 89                 }
 90             }, {
 91                 width: 140,
 92                 title: '用戶',
 93                 render: (text, record) => {
 94                     return (
 95                         <div
 96                         onClick={() => {
 97                             this.setState({
 98                                 visible_pwd: true,
 99                                 user_id: record.id
100                             })
101                         }}
102                         
103                         style={{marginRight: 10, cursor: "pointer", color: '#40a9ff'}}
104                         >
105                               <User   happy={record}  item={record} loadUserList={()=> {
106                                 this._loadUsreList()
107                             }}/>           
108                     </div>
109                     )
110                 }
111 
112             },
113         ]
114     };
115 
116     componentDidMount() {
117         this.getUserList()
118     }
119     //處理六位小數
120     toDecimal=(x)=>{ 
121         var f = parseFloat(x); 
122         if (isNaN(f)) { 
123           return; 
124         } 
125         f = Math.round(x*1000000)/1000000; 
126         return f; 
127     }
128     //處理時間戳
129     timestampToTime = (timestamp) => {
130         var date = new Date(timestamp * 1000);//時間戳為10位需*1000,時間戳為13位的話不需乘1000
131         var Y = date.getFullYear() + '-';
132         var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
133         var D = date.getDate() + ' ';
134         var h = date.getHours() + ':';
135         var m = date.getMinutes() + ':';
136         var s = date.getSeconds();
137         return Y+M+D+h+m+s;
138     }
139 
140 
141     getUserList() {
142         this.setState({loading:true})
143         HttpUtils.postForm('/api/auex/statistics/award/list', {
144             ...this.state.form,
145             order: "id desc",
146             ...this.state.values
147         }).then(res => {
148         this.setState({loading:false})
149             if (res.status == 10000) {
150                 this.setState({
151                     dataSource: res.data,
152                     count: res.count
153                 })
154             }
155             console.log(res);
156         }).catch(err => {
157         this.setState({loading:false})
158             window.$message.error('通訊失敗')
159         })
160     }
161 
162   
163 
164     onSubmit = (value) => {
165         console.log(value)
166         this.setState({
167             form: {
168                 page: 1,
169                 pers: this.state.form.pers,
170 
171             },
172             values: value
173         }, () => {
174             this.getUserList()
175         })
176     }
177     onReset = () => {
178         this.setState({
179             values: {}
180         }, () => {
181             this.getUserList();
182         })
183     }
184 
185     getCurrent = (page) => {
186         console.log(page)
187         this.setState({
188             form: {
189                 page: page,
190                 pers: this.state.form.pers
191             }
192         }, () => this.getUserList())
193     }
194     changePers = (current, size) => {
195         this.setState({
196             form: {
197                 page: current,
198                 pers: size
199             }
200         }, () => this.getUserList())
201     }
202 
203     render() {
204         return (
205             <div>
206                 <PageHeader title="用戶列表" subTitle="查看用戶信息" style={{marginBottom: 20}}/>
207                 <FilterForm select={select} onSubmit={this.onSubmit} onReset={this.onReset} />
208                 <Card>
209                     <Table
210                         loading={this.state.loading}
211                         dataSource={this.state.dataSource}
212                        columns={this.columns }
213                        title={() => `記錄條數:${this.state.count}條`}
214                        pagination={{
215                            showTotal: (total) => {
216                                return <div style={{display: 'flex'}}>
217                                    <div style={{paddingLeft: 18}}>總共{total}條</div>
218                                </div>
219                            },
220                            showSizeChanger: true,
221                            onShowSizeChange: this.changePers,
222                            pageSizeOptions: ['10', '30', '50', '100'],
223                            showQuickJumper: true,
224                            current: this.state.form.page,
225                            total: this.state.count,
226                            onChange: this.getCurrent
227                        }}
228                 />
229                 </Card>
230             </div>
231         )
232     };
233 }
列表頁面

補充:

     0.給子組件傳值  :  <Share happy={record} loadUserList={()=> {this._loadUserList()}}/>   子組件接收值 

     1.設置state中值的時候 不要直接賦值 , 要 使用規范寫法

1 this.setState({ 2                             visible_father: true
3                         })

     2.子組件接到數后不能展示列表? 

1  onClick={() => { 2                         this.setState({ 3                             visible_father: true //修改列表展示為true
4  }) 5                     }}

  3.dataSource中的數據this.props.item 是對象  所以要再外面加一個[] 使其變為數組  

    4.const {number, visible_father, data, loading,} = this.state;  解構賦值后 , 就不需要在this.state.xxx了

    5.<Modal /> 有個visible屬性,表示是否顯示對話框。

占位

 

需要掌握的:

1.Form表單

  • Form.create   經過 Form.create 包裝的組件將會自帶 this.props.form 屬性,this.props.form  常用API :  getFieldDecorator 用於和表單進行雙向綁定,詳見下方描述
class CustomizedForm extends React.Component {} CustomizedForm = Form.create({})(CustomizedForm);

this.props.form.getFieldDecorator(要傳的值, options)

經過 getFieldDecorator 包裝的控件,表單控件會自動添加 value(或 valuePropName 指定的其他屬性) onChange(或 trigger 指定的其他屬性),數據同步將被 Form 接管,這會導致以下結果:

  1. 你不再需要也不應該用 onChange 來做同步,但還是可以繼續監聽 onChange 等事件。

  2. 你不能用控件的 value defaultValue 等屬性來設置表單域的值,默認值可以用 getFieldDecorator 里的 initialValue

  3. 你不應該用 setState,可以使用 this.props.form.setFieldsValue 來動態改變表單值(可以設置默認值)。

  • validateFields  校驗並 獲取 一組輸入域的值與 Error,若 fieldNames 參數為空,則校驗全部組件   /  resetFields 重置一組輸入控件的值(為  initialValue)與狀態,如不傳入參數,則重置所有組件
    handleSubmit = (e) => {
        e.preventDefault();
        this.props.form.validateFields((err, values) => {
            if (err) {
                return;
            }
            values.rate = values.rate / 100;
            window.$http.postForm('/api/', {...this.state.item,...values}).then(res => {
                if (res.status === 10000) {
                    window.$message.success('提交成功!');
                    this.props.form.resetFields();
                    this.setState({visible: false})
                    this.getBonusList()
                } else {
                    window.$message.error(res.message);
                }
            }).catch((err) => {
                window.$message.error('通訊失敗');
            })
        });
    }
  •  Form.Item 表單域

2. Affix 固釘  https://ant.design/components/affix-cn/#header

注意:Affix 內的元素不要使用絕對定位,如需要絕對定位的效果,可以直接設置 Affix 為絕對定位:

<Affix style={{ position: 'absolute', top: y, left: x }}>...</Affix>

3.Card 卡片 https://ant.design/components/card-cn/#header

 

 

 

4.父子傳值   , 傳方法

首先父組件調用子組件,寫一個item = { recodr(columns表單所有數據) }   寫一個 refreshList方法 

 <UpdateCategory item={record} refreshList={() => {
     this.custom_table.getList()
 }}/>

然后再子組件調用 (使用this.props.XXX)調用父組件的XXX

調用屬性 (這里又把父組件的值傳給了子組件CustomForm)
<CustomForm
  content={this.state.content} onSubmit={this.onSubmit} url={'/api/backend/distribution/time/category/save'}
  value={{ id: this.props.item.id }}
  values={this.props.item}
  space={86400}
/>

調用方法

  onSubmit = () => {
     this.setState({
        visible: false
      })
     this.props.refreshList()
  }

 5.彈窗 Modal

6.文本域: const { textArea } = Input  去掉右下角調整大小按鍵 : CSS resize:none;

7.上傳圖片  Upload

8.修改狀態

  {
      // width: 150,
      title: '操作',
      dataIndex: 'status', //verified
      key: 'status',
      render: (text, item) => (
           <>
             {item.status != 1 ? null :
                 <Switch
                     checked={text === 1}
                     onChange={() => {
                         this.changeStatus(text, item.id);
                     }}
                 />}
         </>
       )
  }

 changeStatus(text, id) {
        const toast = window.$message.loading('修改狀態中');
        HttpUtils.postForm(' /api/admin/user/asset/releasedRuleUpdate', {
            id: id,
            status:  2
        }).then(res => {
            toast();
            if (res.status === 10000) {
                window.$message.success('修改狀態成功');
                this.getData();
            } else if(res.status!==18888){
                window.$message.error(res.message);
            }
        }).catch(err => {
            toast();
            window.$message.error('通訊失敗');
        })
    }
 

 9.刪除一行記錄 

{ title: '操作', render: (text, item) => { return ( <div>
                            <Button size={'small'} type={'primary'} onClick={() => { this.props.history.push('/content/carousel/edit/' + item.id) }}> 編輯 </Button>
                            <Popconfirm title="確定要刪除嗎?" okText="確定" cancelText="取消" onConfirm={() => { window.$http.postForm('/api/web/carousel/delete', {id: item.id}).then(res => { if (res.status === 10000) { window.$message.success('刪除成功'); this._loadNewsList() } else if (res.status !== 18888) { window.$message.error(res.message); } }) }} >
                                <Button size={'small'} type={'danger'} style={{marginLeft: 20}} onClick={() => { }}>刪除</Button>
                            </Popconfirm>
                        </div> ); } }

 10 徽標微  

 

import {Badge} from '@ant-design/react-native';

<Badge dot>
            <Touchable style={{position: 'relative'}}>
              <Image source={message} />
            </Touchable>
</Badge>
import {Badge} from '@ant-design/react-native';

<Badge dot>
            <Touchable style={{position: 'relative'}}>
              <Image source={message} />
            </Touchable>
</Badge>

 11. 從接口獲取交易對 / 列表數組

 getSymobls() { HttpUtils.postForm('/api/teacher/trade/exchange/symbols', {}).then(res => { if (res.status === 10000) { let arr1 = new Set(res.data.map((item) => item.symbol)) let symbol = Array.from(arr1).map(item => ({id: item, name: item})); select[2].option = symbol; //添加列表
                this.setState({ select: this.state.select, }) } }).catch((err) => { console.log(err); }) }

 12.如何看懂ant的文檔

 

 

這里提供了2中格式化方式

第一種 告訴你了 value是Date值(日期),date是字符串 ,所以  寫法如下

format={(value) => moment(value).format('YYYY.MM')}

 

 13. 圖片默認列表顯示圖片問題   (解決了,是valueProName的問題  應該要用item.dateIndex)

   

 

 一定要在Upload標簽的外面添加一個父標簽, 不然filelist里的內容無法顯示 

14. 解決單個圖片顯示問題/多個圖片顯示問題/文件顯示問題,保存原有圖片/文件 消失問題  , 這里上傳圖片后 返回了一個圖片地址/多個圖片地址字符串,

上傳組件 

                                <Form.Item
                                    labelCol={{ span: item.labelCol }}
                                    wrapperCol={{ span: item.wrapperCol }}
                                    shouldUpdate
                                    key={item.dataIndex}
                                    label={item.name}
                                    name={item.dataIndex}
                                    valuePropName={item.dataIndex}
                                    getValueFromEvent={normFile}
                                    rules={[
                                        {
                                            required: item.required,
                                            message: item.message,
                                        },
                                    ]}
                                    dependencies={[item.dataIndex]}
                                >
                                     <Upload
                                         fileList={fileList}
                                         className='uploadImg'
                                         listType='picture-card'
                                         headers={{
                                             authorization: sessionStorage.getItem(
                                                 'token',
                                             ),
                                         }}
                                         accept='image/jpeg,image/jpg,image/png'
                                         action='/api/admin/vote/file/upload'
                                         onChange={(value) => {
                                             setVariety(true)  // 有變化和沒變化 傳的值是不同的
                                             console.log('讓我康康',value.fileList);
                                             if (item.images) {
                                                 let arr = [];
                                                 value.fileList.map((item) => {
                                                     let arr_item =
                                                         Object.keys(item)
                                                             .length > 0 && item.url?item.url :  //因為默認給的是一個對象,url在對象里,但是圖片上傳以后,返回的url在對象的response里面 ,所以這里要判斷
                                                         item.response &&  
                                                         item.response.url;  //默認上傳的圖片,會把url放在response里面
                                                     arr.push(arr_item);   
                                                     console.log(
                                                         'item',
                                                         Object.keys(item)
                                                             .length > 0 &&
                                                         item.response &&
                                                         item.response.url,
                                                     );
                                                 });
                                                 console.log('新arr',arr);
                                                 setFileList(value.fileList);
                                                 setImages(JSON.stringify(arr)); 
                                             }
                                             if (item.cover) {
                                                 let cover =
                                                     value.fileList.length > 0 &&  //封面圖因為只有一張圖,不會出現數據結構不一樣的問題,所以不用處理
                                                     value.fileList[0]
                                                         .response &&
                                                     value.fileList[0].response   
                                                         .url;
                                                 setFileList(value.fileList);  
                                                 setCover(cover);
                                             }
                                             setChange(Math.random() + 1);
                                         }}
                                         onPreview={handlePreview}
                                         disabled={item.disabled}
                                     >
                                         {fileList.length >= (item.limit || 1)
                                             ? null
                                             : uploadButton}
                                     </Upload>
                                </Form.Item>

 

打開編輯Modal進行的初始化處理

    useEffect(() => {
        if (props.values) {
            console.log('所有的數據',props.values);

            form.setFieldsValue({ ...props.values });if (props.date) {
                form.setFieldsValue({
                    vote_start: moment(props.values.vote_start * 1000), 
                });
                form.setFieldsValue({
                    vote_end: moment(props.values.vote_end * 1000),
                });
                if (props.values.vote_end === 0) {
                    form.setFieldsValue({ vote_end: null });
                }
                if (props.values.vote_start === 0) {
                    form.setFieldsValue({ vote_start: null });
                }
            }

            if(props.values.name === '封面圖'){
                setFileList([
                    {
                        uid: '-1', //只有一張圖,不用管uid
                        name: 'xxx.png',
                        status: 'done',
                        type: 'image/png',
                        url: props.values['value'],
                    },
                ]);
            }
            if(props.values.name === '輪播圖' && props.values.value.length > 0 ){ //只長度大於0才會解析,防止報錯
                console.log('abc',);

                let arr = []
                let images =  JSON.parse(props.values.value); //這里是JSON字符串,所以要解析
                images.map((item,index)=>{
                    arr.push({
                        uid:index, //uid必須不同,不然會點刪除按鈕,會把所有的圖片都刪除
                        name: 'xxx.png',
                        status: 'done',
                        type: 'image/png',
                        url: item
                    })
                })

                setFileList(arr);
            }
        }
    }, []);

 

 提交處理

    const onSubmit = (values) => {
        if (values.name === '封面圖' ) { //沒有更好的判斷方法 if(variety){ //如果發生了變化,傳自己修改的JSON字符串
                values.value = cover;
            }else { //沒有發生變化,就返回原來的
                values.value = props.values.value;
            }
        }
        if (values.name === '輪播圖' && images.length > 0) {
            if(variety){
                values.value = images;
            }else {
                values.value = props.values.value;
            }
        }
        values = onCheckValues(values);
        setLoading(true);
        Http.postForm(props.url, {
            ...props.value,
            ...values,
        })
            .then((res) => {
                setLoading(false);
                if (res.status === 10000) {
                    message.success('提交成功');
                    props.onSubmit();
                } else {
                    message.error(res.message);
                }
            })
            .catch((err) => {
                setLoading(false);
                message.error('通訊失敗');
            });
    };

 

 

 

上傳文件的組件代碼

                        case 'upload':
                            return (
                                <Form.Item
                                    shouldUpdate
                                    key={item.dataIndex}
                                    label={item.name}
                                    labelCol={{ span: item.labelCol }}
                                    wrapperCol={{ span: item.wrapperCol }}
                                    name={item.dataIndex}
                                    valuePropName={item.dataIndex}
                                    getValueFromEvent={normFile}
                                    rules={[
                                        {
                                            required: item.required,
                                            message: item.message,
                                        },
                                    ]}
                                    dependencies={[item.dataIndex]}
                                >
                             <Upload
                                 fileList={fileList2}
                                 action='/api/admin/vote/file/upload'
                                 headers={{
                                     authorization: sessionStorage.getItem(
                                         'token',
                                     ),
                                 }}
                                 onChange={(value) => {
                                     setVariety2(true);
                                     if (item.file) {
                                         let file =
                                             value.fileList.length > 0 &&
                                             value.fileList[0]
                                                 .response &&
                                             value.fileList[0].response
                                                 .url;
                                         setFile(file);
                                     }
                                     setFileList2(value.fileList);
                                     setChange(Math.random() + 1);
                                 }}
                                 disabled={item.disabled}
                             >
                                 {fileList2.length >= 1
                                     ? null
                                     :  <Button>
                                         <UploadOutlined /> 點擊上傳
                                     </Button>}
                             </Upload>
                                </Form.Item>
                            );

 

壓縮文件顯示初始化

           props.values.download_address.length > 0 &&  setFileList2([{
                uid: '-1',
                name: `${props.values.company_name}.zip`,
                status: 'done',
                type: 'application/zip',  
                url:  props.values['download_address']
            }])

 

效果圖  :

 

 

 

 

 

 

 

 


免責聲明!

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



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