• Ant Design Pro 单个页面目录结构以及一些常见的报错


    一、Ant Design Pro新增单个页面目录

    1、 client -> src -> pages 中新增文件夹,比如 category的list

    ├── category

      └── list

             └── _mock.js   //  模拟数据(可忽略)

             └── model.js   //  处理请求的model组件,如果简单请求,直接写到 index.jsx中,简单化。(可忽略)

             └── index.jsx  //  主要的核心文件

      └── service.js   // 接口请求合集

      └── style.less  // category 公共样式

    2、在 client ->  config -> conifig.js 中 配置的routes 或者 route.js 中添加路由

    {
      path: '/category',
      name: '分类',
      icon: 'category',
      routes: [
       {
         path: '/category/list',
          name: '分类列表列表',
          component: './category/list'
        }
      ]
    },   

    index.jsx

    import React, { Component } from 'react';
    import { PageContainer } from '@ant-design/pro-layout';  // 引入布局组件
    import { Card, Table, Select, Form, DatePicker, Button, Pagination } from 'antd';  // 引入ant design ui组件
    import { getCategoryList } from '../service'; // 引入请求接口
    import moment from 'moment';  // 时间日期组件,时间格式
    import styles from '../style.less';  // 引入公共样式,styles.class
    
    const { Option } = Select;  // 下拉框引入 Option
    const { RangePicker } = DatePicker;  // 时间日期组件引入 RangePicker
    const dateFormat = 'YYYY-MM-DD';  // 时间日期格式
    
    // 筛选项变量
    const selectData = [
    {
      label: '所属渠道',
      name: 'channel',
      style: {
         '100px'
      },
      options: [
        {
          value: 'website',
          name: '站内',
    
        },
        {
          value: 'email',
          name: '邮件',
    
        }
      ]
    },
    ];
    
    // 创建类组件实例
    class categoryList extends Component {
      // 获取 DOM 元素节点,通过设置 ref,这里是表单form的ref
      formRef = React.createRef();
    
      constructor(props) {
          super(props);
          this.state = {
             channel: '',
             selectSourceData: [],
             categoryListSource: [],
          }
      }
    
      // 数据初始化
      componentDidMount() {
         // 获取categoryList数据,注意最好不要和service中函数名重复
         this.getCategoryListFn();
    
         // 设置筛选项
         this.setState({
            selectSourceData: selectData
        })  
      };
    
      // 获取 categoryList
      getCategoryListFn = ( params ) => {
         params = params ? params : { chanel: 'website' };  // 设置一个默认值,可随意自定义
      
         getCategoryList({ ...params }).then(res => {  // 可以定义分页参数
            if (res.status == 200 ) {
                const { data } = res;
                this.setState({
                    categoryListSource: data.list
                })
            }
        });
      }
    
      // 切换筛选项
      selectChange = (value, attr) => {
         // 双向绑定
         this.setState({
            [attr.key]: value
         });
    
        // 自定义其他操作
      }    
    
        // 重置
      onReset = () => {
        this.formRef.current.resetFields();
    
        // 重置初始化
        this.setState({
          selectSourceData: selectData
        })
      };
    
       // 搜索提交,请求list,更新table
      onFinish = (values) => {
         this.getStatDataFn({
           channel: values.channel || '',
        })
      }
    
       // render
       render() {
          const columns = [
             {
                title: '推送时间',
                dataIndex: 'push_time',
                key: 'push_time',
                align: 'center',
                 150,
              },
              {
                title: '事件名称',
                dataIndex: 'event_name',
                key: 'event_name',
                align: 'center',
                 150,
              },
            ];
    
            const { loading } = this.props;
            const { dateRange, selectSourceData, categoryListSource} = this.state;
    
            return (
                <PageContainer>
                      <Card
                          className={styles.tabsCard}
                        >
                          <Form
                            layout="inline"
                            ref={this.formRef}
                            name="searchObj"
                            className={styles.formBox}
                            initialValues={{
                              channel: '',
                              dateRange: [],
                            }}
                            onFinish={this.onFinish}
                            onReset={this.onReset}
                          >
                            {selectSourceData.map(item => (
                            <Form.Item 
                                name={item.name} 
                                label={item.label} 
                                key={item.name} 
                                className={styles.formItem}
                             >
                                <Select 
                                  value={item.name}
                                  style={item.style} 
                                  placeholder="请选择"
                                  disabled={item.disabled}
                                  onChange={this.selectChange}
                                >
                                  {item.options.map((val, index) => (
                                    <Option key={index} disabled={val.disabled} type={item.name} value={val.value}>{val.name}</Option>
                                  ))}
                                </Select>
                          </Form.Item>
                        ))}
                
                     <Form.Item 
                          key='dateRange'
                          name="dateRange"  
                          className={styles.formItem}
                        >
                          <RangePicker 
                            value={dateRange.length ? [moment(dateRange[0], dateFormat), moment(dateRange[1], dateFormat)] : null}  // 重置设置
                            type="dateRange"
                            placeholder={['开始时间', '结束时间']}
                            format={dateFormat}
                            onChange={(value, dateString) => {
                              this.setState({
                                dateRange: dateString
                              })
                            }}
                          />
                        </Form.Item>
                        <Form.Item>
                          <Button type="primary" htmlType="submit">搜索</Button>
                        </Form.Item>
                        <Form.Item>
                          <Button type="default" htmlType="reset">重置</Button>
                        </Form.Item>
                      </Form>
    
                      <Table
                        dataSource={categoryListSource}
                        bordered={true}
                        scroll={{ x: 2400 }}  // 超出滚动,最大宽度
                        columns={columns}
                        rowKey={(record, index) => index}
                        // pagination={pagination}
                        // pagination={false}
                        loading={loading}
                        // onChange={this.handleTableChange}
                      />
                    </Card>
                </PageContainer>
            )
       }
    }                

    service.js

    // 封装axios,拦截器interceptors
    import request from '@/utils/request';
    
    // 获取分类列表
    export async function getCategoryList(params) {
      return request('/admin/report/get-category-list', {
        method: 'POST',
        data: params,
      });
    }

    二、编译可能出现警告:

     There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these module identifiers
     1、新增文件夹名注意都要小写,如果多个单词,用横杠 — 隔开

     2、import 引入的文件注意文件名的大小写: impor request form '../utils/request.js'

     Each child in a list should have a unique "key" prop,Check this render methods of  'Body'

     1、如果是table组件,官方给 Table 组件提供了一个 rowKey 属性,用于给表格的每一行设定一个 key 值

    <Table
        dataSource={this.state.tableDataSource}
        rowKey={(record, index) => index}  // 或者 record.id,index好像启用了,最好用唯一字段或者拼接字段
    >
    </Table>

     2、如果是 map() 循环,遍历的时候也必须给 key 值

    {list.map((item, index) => {
        <p key={index}>{{item}}</p>
      })
    }

     Missing message: "menu.分类管理.分类列表" for locale: "zh-CN", using default message as fallback

    这是菜单翻译缺少,请求的菜单需要同步更新

    找到 client -> src -> locales -> zh-CN -> menu.js 

    'menu.分类管理.分类列表': '分类列表',

    三、本地开发 menu 导航栏无法加载问题 (https://github.com/ant-design/ant-design-pro/issues/7530

     1、找到 client -> defaultSettings.js, 里面 menus 先注释掉

     2、找到 client -> src -> layouts -> Basiclayout.jsx,找到里面 ProLayout  标签,在 menuDataRender 属性配置上面加上配置 menu={{ loading }}

    四、componentDidmount 获取父组件 this.props 中异步数据的失效

      这个时候,可以使用更新过程中生命周期 componentWillReceiveProps(nextProps) 来获取异步ajax请求的数据 nextProps

      1、在接受父组件改变后的 props 需要重新渲染组件时用到的比较多

      2、接受一个参数 nextProps

      3、通过对比 nextProps 和 this.props,将 nextProps 的state为当前组件的state,从而重新渲染组件

    五、ant design 关于 Datepicker 限制时间范围和默认时间

     1、限制时间范围

    // 使用disbledDate,当前时间到前7天内选择时间, 关于moment.js参考官网 http://momentjs.cn/
    const disabledDate = (current) => {
        // moment().subtract(7, "days") 表示当前日期往前推移7天
        // moment().endOf( "day")  表示当前日期最后的时间23:59:59
        return current && (current < moment().subtract(7, "days") || current >= moment().endOf('day')
    }
    
    <RangPicker disabledDate={this.disabledDate}>

    2、默认时间

    const dateFormat = 'YYYY-MM-DD';
    
    this.state = {
      // 当前时间到前30天内  
      dateRange: [moment().subtract(30, 'days'), moment()],  
    }
    
    <RangePicker 
        value={dateRange.length ? [moment(dateRange[0], dateFormat), moment(dateRange[1], dateFormat)] : null}
        type="dateRange"
        format={dateFormat}
        disabledDate={this.disabledDate}
    >
    </RangePicker>
  • 相关阅读:
    04.sys
    leetcode算法-加油站
    Spring动态AOP
    (java反射-JDK动态代理)+CGLIB动态代理
    java反射-基础语法
    leetcode算法-验证回文串
    leetcode算法-盛最多水的容器
    leetcode算法-两数之和
    leetcode算法-三数之和
    leetcode算法-最长和谐子序列
  • 原文地址:https://www.cnblogs.com/cp-cookie/p/14776353.html
Copyright © 2020-2023  润新知