天天看點

Ant Design Pro V5 ProTable的使用技巧

Ant Design Pro ProTable

    • 基礎配置說明
      • ProTable
      • columns
    • 基礎使用
    • 遇到的問題
    • 建議
    • 最後

在此先說一下基礎使用,後面再講我遇到的問題

基礎配置說明

配置也可以去官方文檔,不過官方文檔有些不是很全,我這裡主要寫一些基礎需要用到的配置,補充一下官方文檔沒有的

https://procomponents.ant.design/components/table

ProTable

屬性 描述 類型 額外說明
request 擷取dataSource的方法

(params?: {pageSize: number;current: number;[key: string]: any;},sort,filter) => Promise<RequestData<T>>

如果後端傳回的格式符合RequestData就可以直接将請求的函數傳回值給到request,否則需要自己去轉換,RequestData格式這裡說一下基礎的幾個字段:

{data:T[],total?:number}

,pageSize和current是直接取的request的參數,而不是傳回的參數
columns table表頭字段

{title:string,dataIndex:string,key:string|number}

-
actionRef Table action 的引用,便于自定義觸發

React.MutableRefObject<FormInstance> | ((actionRef: ActionType) => void)

其實就是一個DOM元素,隻不過table給他加了一些方法,可以進行table的重新整理,以及search的重置,具體可以看我下面代碼如何初始化這個actionRef
toolBarRender 渲染工具欄,支援傳回一個 dom 數組,會自動增加 margin-right

(action: UseFetchDataAction<RequestData<T>>) => React.ReactNode[]

注意:是傳回一個ReactNode數組,不然會報錯PlusOutlined is not defined
rowKey 用什麼字段作為每行的key string rowKey=‘id’最好寫上,減少重複dom渲染
dateFormatter 轉化 moment 格式資料為特定類型,false 不做轉化 string | number | false -
headerTitle title string -
search 是否顯示搜尋表單,傳入對象時為搜尋表單的配置 optionRender:右側按鈕;span:form表單自定義自适應;labelWidth:formLabel寬度
pagination 分頁配置 詳細配置 -
onSubmit search表單送出觸發

(values:any) => void

點選重置也會觸發,我的解決方式是利用onReset和boolean變量結合
params 用于 request 查詢的多餘參數,一旦變化會觸發重新加載 object -

columns

屬性 描述 類型 額外說明
request 擷取select的選項

(params: U, props: T) => Promise<{label: React.ReactNode;value: React.ReactText;[key: string]: any;}[]>

需要傳回一個數組,每個元素有value和label對象
valueEnum 值的枚舉,會自動轉化把值當成 key 來取出要顯示的内容

[key: string]: | React.ReactNode | {text: React.ReactNode;status: 'Success' |'Error' | 'Processing' | 'Warning' | 'Default'; };

注意是對象而不是數組,value可以是ReactNode,可以是含有text和status的對象
ellipsis 是否自動縮略 boolean 記得要設定width哦,否則不會省略,隻會有一個tips
valueType 值的類型 money| option | date | dateTime | time | text| index|indexBorder option這個類型可以讓傳回的數組中每個ReactNode有一定的間距
render 類似 table 的 render,第一個參數變成了 dom,增加了第四個參數 action

(text: React.ReactNode,record: T,index: number,action: UseFetchDataAction<RequestData<T>>) => React.ReactNode | React.ReactNode[]

一般用于操作按鈕,如果隻是普通的展示可以用renderText
hideInSearch 是否展示搜尋框 boolean -
hideInTable 在 Table 中不展示此列 boolean -
order 查詢表單中的權重,權重大排序靠前 number -

基礎使用

下面這個例子我盡量把常用的和難點都用上

這裡是用的hooks的寫法,hooks相信大家也很熟悉了,就不多說了

import React, { useState} from 'react';
import {Button} from 'antd';
import ProTable, { ProColumns } from '@ant-design/pro-table';
import {PageContainer} from "@ant-design/pro-layout";
import {formatMessage} from "@@/plugin-locale/localeExports";
import {FormattedMessage,history} from "umi";
import {getHistorryList} from './service'
import {getCategories} from "@/pages/Home/demand/Update/service";
import {PlusOutlined} from '@ant-design/icons'


export default ()=>{
  const [category,setCategory] = useState<any>();
  // 擷取需求類型
  async function getType(){
   let res = await getCategories();
   if(res){
     let categor = {};
     for(let item of res.data){
       categor[item.id] = item.name;
     }
     setCategory(categor)
     return res.data.map(item=>({label:item.name,value:item.id}))
   }
  }
  // columns
  const columns: ProColumns[] = [
    {
      title: formatMessage({id:'demand.history.title'}),
      dataIndex: 'title',
      // valueType: 'indexBorder',
      hideInSearch: true,
      width:200,
      ellipsis:true,
    },
    {
      title: formatMessage({id:'demand.history.type'}),
      dataIndex: 'category',
      valueEnum:category,//這一列是後端傳回的資料,目前還沒有找到好的方法可以直接讓搜尋框和table展示資料一緻,隻能外加一個valueEnum讓table展示正确資料
      request:async()=>getType(),
    },
    {
      title: formatMessage({id:"demand.history.crux"}),
      dataIndex: 'title',
      hideInTable:true,
    },
    {
      title: formatMessage({id:'demand.history.reply'}),
      dataIndex: 'reply',
      ellipsis: true,
      hideInSearch: true,
      width:200
    },
    {
      title: formatMessage({id:'workorder.my.status'}),
      dataIndex: 'status',
      hideInSearch: true,
      filters: true,
      valueEnum:{
        1:{
          status:"Processing",text:formatMessage({id:'demand.history.already.submit'})
        },
        2:{
          status:'Success',text:formatMessage({id:'demand.history.adopt'})
        },
        3:{
          status:'Error',text:formatMessage({id:'demand.history.no.adopt'})
        }
      }
    },

    {
      title:  formatMessage({id:'demand.history.time'}),
      dataIndex: 'createTime',
      valueType: 'dateTime',
      hideInSearch: true,
    },
    {
      title: formatMessage({id:'workorder.my.option'}),
      valueType: 'option',
      dataIndex: 'id',
      render: (text, row) => [
        <a key="show" href={row.html_url} target="_blank" rel="noopener noreferrer">
          <FormattedMessage id="workorder.my.details"/>
        </a>,
        <a key="show" href={row.html_url} target="_blank" rel="noopener noreferrer">
          <FormattedMessage id="workorder.my.details"/>
        </a>,
      ],
    },
  ];

  return (
    <PageContainer>
      <ProTable
        pagination={{pageSize:10,current:1}}
        columns={columns}
        request={async (params = {}) => getHistorryList(params)
        }
        rowKey="id"
        dateFormatter="string"
        headerTitle="需求建議"
        search={{
          optionRender: ({ searchText, resetText }, { form }) => [
            <Button
              type="primary"
              key="search"
              onClick={() => {
                form?.submit();
              }}
            >
              {searchText}
            </Button>,
            <Button
              key="reset"
              onClick={() => {
                form?.resetFields();
                form?.submit();
              }}
            >
              {resetText}
            </Button>,
          ],
        }}
        toolBarRender={() => [
          <Button key="3" type="primary" onClick={()=>{
            history.push('/home/demand/update')
          }}>
            <PlusOutlined />
            <FormattedMessage id='menu.home.update'/>
          </Button>,
        ]}
      />
    </PageContainer>
  );
}
           
Ant Design Pro V5 ProTable的使用技巧

遇到的問題

  1. 在最後一欄操作中,正常render函數傳回一個數組,就會有間距,但是容易犯一些小錯誤,比如render寫成renderText函數,沒有寫valueType:option都會導緻沒有間距,是以完整的代碼是這樣的:
{
      title: formatMessage({id:'workorder.my.option'}),
      valueType: 'option',
      render: (text, row) => [
        <a key="show" href={row.html_url} target="_blank" rel="noopener noreferrer">
          <FormattedMessage id="workorder.my.details"/>
        </a>,
        <a key="show" href={row.html_url} target="_blank" rel="noopener noreferrer">
          <FormattedMessage id="workorder.my.details"/>
        </a>,
      ],
    },
           
  1. 在valueEnum中status首字母要大寫,原本以前是可以的,後來估計是更新了就不行了,必須大寫,否則前面的狀态點點不會顯示出來
valueEnum:{
        1:{
          status:"Processing",text:formatMessage({id:'demand.history.already.submit'})
        },
        2:{
          status:'Success',text:formatMessage({id:'demand.history.adopt'})
        },
        3:{
          status:'Error',text:formatMessage({id:'demand.history.no.adopt'})
        }
      }
           
  1. 分頁:預設是20條一頁,可以在proTable中加入 pagination={{pageSize:10,current:1}}代碼就可以了,不過文檔沒說,害!!!
  2. 在table中顯示的字段和搜尋的字段不同時,其實可以這樣将key設定為搜尋的字段,例如:
{
      title: formatMessage({ id: 'workorder.my.currentDispose' }),
      dataIndex: 'handleUserName',
      width: 150,
      key: 'handleUser',
}
           

建議

最後還是說一下使用pro元件的注意事項:

  1. 不要盲目拿起案例直接copy,可以先看一遍他的配置表
  2. 有特殊需求的時候看配置表是否能實作,無法實作再想别的辦法
  3. 如果文檔沒有寫某參數的用法,或者該元件有哪些參數,可以點進源碼看看,d.ts檔案裡面就會清楚的看到
  4. 盡量讓後端傳回的資料符合元件所需的資料格式,否則需要自己轉換資料

最後

感謝大家的支援,我會持續更新的,不懂的可以直接評論問我,我盡力幫各位解答

繼續閱讀