Antd Pro V4 protable详解(ps:踩坑日记)

Antd Pro V4 protable详解(ps:踩坑日记)

写在前面:
在这篇文章中,你会了解到:

  • protable 中的cloumns属性详解
  • protable数据加载和处理(两种方法,直接使用service或者使用models)
  • 一些笔者踩过的小坑
  • 在将model与Protable结合时的疑问
一、ProTable概要

1.为什么需要ProTable?
antd pro 中的大部分组件来自于 antd , 而 antd pro table 则是基于 antd 的 table 组件再封装了一层, 熟练使用 antd pro table, 能够覆盖大部分增删改查业务的需要, 关键是只需要极少的配置, 就能得到一个完善的表格。引用官方的话来说,那就是

antd 作为服务于企业级产品的设计体系的组件库,已经提供了强大的 Table,但是业务的不同导致我们仍有需要进行一些定制,不同的单元格有很多不同的数据格式,金额,日期,数字等,包括一些常用的操作,页码切换时的重新请求,刷新数据等,这些都是很简单的重复劳动,但是却不可避免。

ProTable 就是为了解决这些问题,在 Table 的层面上提供了一些预设,你可以通过 valueType 来支持各种类型的数据,预设了金额,日期,序号,进度条 等多种类型,并且支持通过 valueEnum 来映射枚举,解决非常烦人的各种枚举配置,可以大大的简化代码。

综上,一言以蔽之,ProTable is fucking awesome!(But还是有一些小问题需要解决。)

2.ProTable的主要板块
Antd Pro V4 protable详解(ps:踩坑日记)_第1张图片
在大部分场景中,我们只需要配置这四种颜色的板块即可:

  • 红色:search属性,搜索表单,传入对象时为搜索表单的配置,设置是否显示,默认为true
  • 绿色:通过,toolBarRender进行配置,渲染工具栏,支持返回一个 dom 数组,会自动增加 margin-right
  • 蓝色:通过rowSelection(已经选择项),tableAlertRender(当前共选中 1 项,共有 1 项未解决),tableAlertOptionRender(自定义 清空)三个属性进行配置
  • 棕色:通过columns进行配置,也就是表头。
<ProTable
      columns={columns}
      request={async (params = {}) =>   //请求数据
        request('https://proapi.azurewebsites.net/github/issues', {
          params,
        })
      }
      rowKey="id"
      rowSelection={{}}
      tableAlertRender={({ selectedRowKeys, selectedRows }) =>
        `当前共选中 ${selectedRowKeys.length} 项,共有 ${selectedRows.reduce((pre, item) => {
          if (item.state === 'open') {
            return pre + 1;
          }
          console.log(selectedRowKeys,selectedRows)
          return pre;
        }, 0)} 项未解决 `
      }
      tableAlertOptionRender={props => {
        const { onCleanSelected } = props;
        return (
          <Space>
            <a>自定义</a>
            <a onClick={onCleanSelected}>清空</a>
          </Space>
        );
      }}
      dateFormatter="string"
      headerTitle="批量操作"
      toolBarRender={(_, { selectedRowKeys }) => [   //配置绿色框中的内容
        <Button key="3" type="primary">
          <PlusOutlined />
          新建
        </Button>,
        selectedRowKeys && selectedRowKeys.length && (
          <Button
            key="3"
            onClick={() => {
              window.alert(selectedRowKeys.join('-'));
            }}
          >
            批量删除
          </Button>
        ),
      ]}
    />
二、ProTable详解

1.cloumns
以下笔者把一些需要尝试才能试出来的属性标注,其余一看文档就懂的属性,笔者就不赘述了

const columns = [
  {
    title: '序号',  // 对应表头的文字
    dataIndex: 'index',  //对应你的字段名称
    valueType: 'indexBorder',  //indexBorder就是proTable自动帮你生成的1,2,3,4的序号
    width: 72,    //通过width属性, 可以自行调节这一栏的宽度,不过总宽度不要超过100%哦
  },
  {
    title: '标题',
    dataIndex: 'title',
    copyable: true,    //多出来一个蓝色的复制icon,点击就直接进行复制
    ellipsis: true,   //用...代替没有显示的文本,并且在鼠标移到相应的文本上会显示全部的相应文本
    tip: '标题过长会自动收缩',   //显示在表头作为一个提示
    width: '30%',
    hideInSearch: true,   //在最上面的搜索栏不显示该字段
  },
  {
    title: '状态',
    dataIndex: 'state',
    initialValue: 'all',
    filters: true,
    valueEnum: {
      all: {  //key表示选中该状态后,所获得的值
        text: '全部',  //text表示实际显示出来的文本
        status: 'Default',  //表示文字前面的那一个点是什么颜色
      },
      open: {
        text: '未解决',
        status: 'Error',  //表示文字前面的那一个点是什么颜色 :红色
      },
      closed: {
        text: '已解决',
        status: 'Success', //表示文字前面的那一个点是什么颜色 :绿色
      },
      processing: {
        text: '解决中',
        status: 'Processing',
      },
    },
    width: '10%',
  },
  {
    title: '标签',
    dataIndex: 'labels',
    width: '10%',
    render: (_, row) => (  //自定义渲染方法,返回一个ReactNode,row就是这一整行的数据
      <Space>
        {row.labels.map(({ name, id, color }) => (
          <Tag color={color} key={id}>
            {name}
          </Tag>
        ))}
      </Space>
    ),
  },
  {
    title: '创建时间',
    key: 'since',
    dataIndex: 'created_at',
    valueType: 'dateTime',
    width: '20%',
  },
  {
    title: '操作',
    valueType: 'option',
    render: (text, row, _, action) => [  
    //自定义渲染方法,返回一个ReactNode,row就是这一整行的数据
      <a href={row.html_url} target="_blank" rel="noopener noreferrer" key="link">
        链路
      </a>,
      <a href={row.html_url} target="_blank" rel="noopener noreferrer" key="warning">
        报警
      </a>,
      <a href={row.html_url} target="_blank" rel="noopener noreferrer" key="view">
        查看
      </a>,
      <TableDropdown
        key="actionGroup"
        onSelect={() => action.reload()} 
        // action 是Form.useForm暴露出来的对象,便于手动触发表格操作
       
        menus={[
          {
            key: 'copy',
            name: '复制',
          },
          {
            key: 'delete',
            name: '删除',
          },
        ]}
      />,
    ],
  },
];

2.数据加载:跳过models,直接使用service进行API管理

首先是页面初始化的时候,通过request属性加载相应的数据,request属性,携带当前页数(current)和页面数据量(pageSize)两个变量,但是在改变当前页数,都会再次触发request发起请求。
Antd Pro V4 protable详解(ps:踩坑日记)_第2张图片
index.jsx

import {getData,changeData} from './service'
....省略
 <ProTable
    ...省略
    request = {async (params)=>{
    	let data = Object.assign(params,...把其它需要的参数,绑定到params)
		let res = await getData(data)
        return {
            data:data ,
            success:true
            total:data.total
        }
    }}
    
    
  />

service.js
小tips,request中,如果key为params会将参数拼接在地址后面,而data,则是会将参数放在请求体中,并且PUT,DELETE方法也是使用data属性

import request from '@/utils/request'

export async function getData(params){
    return request('/api/test',{
        params:params
    })
}

export async function changeData(params){
    return request('/api/test',{
        data:params,
        methods:"POST"
    })
}

返回数据格式的坑:
Antd Pro V4 protable详解(ps:踩坑日记)_第3张图片
大家要注意的一点是,request属性对于返回的数据格式是有要求的

request={async (params = {}) =>
      {
        console.log("params",params)
        return {
				data: dataSource,
			    total: tableListDataSource.length,
			    success: true,
			    pageSize,
			    current: parseInt(`${params.currentPage}`, 10) || 1,
			}
      }
    }

特别是前三个data,total,success字段,如果没有的话,页面是没有数据的,刚开始用pro的时候,笔者在这里踩过坑, 标注一下!

ps:如果用户在进入页面的时候不需要自动触发request请求数据,需要用户手动查询之后,才会获取到数据,只需要添加一个。manualRequest = {true}属性即可,但注意,添加这个属性之后,最上方的serach就是不可隐藏的了。

3.数据更新,调用action

/**
 * 添加节点
 * @param fields
 */

const handleAdd = async fields => {   //添加数据
  const hide = message.loading('正在添加');

  try {
    await addRule({ ...fields });  //调用相应的service中的api即可
    hide();
    message.success('添加成功');
    actionRef.current.reload()   //刷新表格,触发request属性拉取最新数据
  } catch (error) {
    hide();
    message.error('添加失败请重试!');
    
  }
};

其它action操作

// 刷新
ref.current.reload();
// 加载更多
ref.current.fetchMore();
// 重置到默认值
ref.current.reset();
// 清空选中项
ref.current.clearSelected();

ps:这里只是对于是否成功发起请求进行了判断,但是如果要进行错误处理的话,目前根据umi-request官方的说法,最多只能在model中的effect或者reducer中进行处理,无法直接在umi-request使用中间件或者用其它方法在源头处理,umi-request即使请求失败,依旧会把失败的相应返回给用户。

4.疑问:将model与ProTable结合
这是问题示范,笔者还没有实践成果过,大家注意
(1)写service

import request from '@/utils/request'

export async function getData(params){
    return request('https://proapi.azurewebsites.net/github/issues',{
        params:params
    }) //此处笔者直接使用官方提供的api作为测试api
}

(2)写model

import {getData,changeData} from './service'

const TestModel = {
    namespace:"TestModel",
    state:{
        testData:[]
    },
    effects:{
        *fetchTestData({payload},{put,call}){
            const response = yield call(getData,payload)  //调用api
            yield put({  //触发saveData这个reducer
                type:"saveData",
                payload:response
            })
        }   
    },
    reducers:{
        saveData(state,action){
            return {...state,testData:action.payload || {}}  //将获取到的数据合并到state中
        }
    }
}

export default TestModel

(3)将dispatch和state连接到组件上

import {connect} from 'dva'
export default connect(({TestModel})=>({  //TestModel是相应的namespace
    testData:TestModel.testData
}))(Test)

(4)将dispatch写入request属性中,并且将testData赋给dataSource属性(用来初始化table)

<ProTable
            。。。省略
            request = {(params)=>{

                dispatch({
                    type:"TestModel/fetchTestData",
                    payload:params
                })
            }}
            dataSource={testData}
            
            
        />

这样即使数据格式正确,pro仍然无法正确显示数据,一脸懵逼。。。。


以上就是关于Protable的全部内容
详情请查阅官方文档:ProComponents

感谢阅读,欢迎批评指正,希望大家能够在追求卓越中不断进步,让优秀成为一种习惯~

你可能感兴趣的:(react,ant,js)