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                 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                  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.修改状态

  {
      //  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']
            }])

效果图  :

 

 

 
原文地址:https://www.cnblogs.com/it-Ren/p/11445890.html