亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

React通過hook實現(xiàn)封裝表格常用功能

 更新時間:2023年12月30日 09:43:58   作者:sanhuamao  
這篇文章主要為大家詳細介紹了React通過hook封裝表格常用功能的使用,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下

封裝內(nèi)容

  • 配置分頁:usePagination
  • 生成過濾項:useFilter
  • 獲取表格選擇配置:useSelect
  • 生成批量刪除按鈕:useDelete
  • 生成模態(tài)框:useModal

基于react@18.2.0,antd@5.12.5

示例

render部分:

<React.Fragment>
    <Form layout="inline">
    {DeleteEle}
    {FilterEles}
    </Form>
    <Table
    {...{
        columns,
        dataSource: list || [],
        rowSelection,
        pagination: paginationConfig,
        rowKey: 'inform_uuid',
    }}
    />
    {ModalEle}
</React.Fragment>

效果:

完整代碼

import React, { useState, useEffect } from 'react';
import { Form, Table, Tag } from 'antd';
import Detail from './Detail'; // 詳情彈框的內(nèi)容
import { LIST_RES } from '../store'; // 模擬請求數(shù)據(jù)
import TableGenerator from '../TableGenerator'; // 封裝的鉤子

const { useFilter, usePagination, useSelect, useDelete, useModal } =
   TableGenerator;

const TestTable = () => {
   // 1. 生成過濾項。
   // 傳入配置,可以自行擴展。目前支持輸入框、日期范圍選擇器、普通選擇器
   // FilterEles:過濾項表單項
   // filterRefresh:暴露出來告訴外層需要重新獲取數(shù)據(jù)了
   const { FilterEles, filter, filterRefresh } = useFilter([
      {
         name: 'name', // 字段
         label: '平臺名稱', // placeholder
         type: 'inputString', // 組件類型:字符串輸入框
      },
      {
         name: 'status',
         label: '狀態(tài)',
         type: 'select', // 組件類型:選擇器
         initValue: 0, // 默認數(shù)據(jù)(可選)
         options: [
            { value: 0, label: '全部狀態(tài)' },
            { value: 1, label: '成功' },
            { value: 2, label: '失敗' },
         ],
      },
      {
         name: ['start_date', 'end_date'],
         label: ['開始日期', '結(jié)束日期'],
         type: 'dateRange', // 組件類型:日期選擇器
      },
   ]);

   // 2. 獲取分頁配置。
   // pagination:{page,pageSize,total}
   // pageRefresh:暴露出來告訴外層需要重新獲取數(shù)據(jù)了
   // paginationConfig:作為表格的分頁屬性
   const { pagination, setPagination, pageRefresh, paginationConfig } =
      usePagination();

   // 3. 表格選中配置
   // selectedKeys: Array<string>
   // rowSelection: 作為表格的選擇屬性
   const { selectedKeys, setSelectedKeys, rowSelection } = useSelect();

   // 4. 配置模態(tài)框。
   // 傳入數(shù)組,用于配置所有彈框類型(詳情、添加、編輯等),目前只支持詳情,可自行擴展
   // ModalEle: 模態(tài)框組件
   // modal: {isShow:boolean, action:string, record:any}
   const { ModalEle, modal, setModal } = useModal([
      {
         title: '詳情', // 彈框標題
         action: 'detail', // 彈框類型
         getComponent: (record) => <Detail data={record} />, // 彈框數(shù)據(jù)
         // ... 可以繼續(xù)添加屬性,其他屬性將會應用到Modal中 比如footer、handleOk
      },
   ]);

   // 5. 批量刪除按鈕,需要搭配useSelect使用
   const [DeleteEle] = useDelete({
      url: 'ajax/deleteItem.json',
      data: {
         uuids: selectedKeys,
      },
      success: () => {  // 可選,刪除成功后還需要調(diào)用的內(nèi)容
         setSelectedKeys([]);
         getList();
      },
      keys: selectedKeys, // 用于判斷按鈕是否可點擊
   });

   const [list, setList] = useState([]);
   const getList = () => {
      // 請求數(shù)據(jù), 可傳入filter和pagination作為參數(shù)
       Ajax.ajax({
         url: 'GetSmsInformList',
         data: {
            page: pagination.page,
            pageSize: pagination.pageSize,
            filter
         },
         success: (data) => {
            setList(data.list);
            setPagination({
               ...pagination,
               page: data.page,
               total: data.total
            });
         }
      });
      
      // 模擬數(shù)據(jù)
      // const data = LIST_RES.data;
      // setList(data.list);
      // setPagination({
      //   ...pagination,
      //   page: data.page,
      //   total: data.total,
      // });
   };
   // 觸發(fā)刷新:修改page、pageSize、點擊查詢、重置時將會觸發(fā)
   useEffect(() => {
      getList();
   }, [pageRefresh, filterRefresh]);

   const columns = [
      {
         title: '序號',
         width: 50,
         align: 'center',
         render: (v, r, index) =>
            index + 1 + (pagination.page - 1) * pagination.pageSize,
      },
      {
         title: '平臺名稱',
         width: 180,
         dataIndex: 'req_psname',
      },
      {
         title: '請求時間',
         width: 140,
         dataIndex: 'inform_time',
      },
      {
         title: '通知對象',
         width: 180,
         dataIndex: 'inform_pnumbers',
         render: (v) => v.join(', '),
      },
      {
         title: '通知內(nèi)容',
         width: 200,
         dataIndex: 'inform_content',
      },
      {
         title: '通知結(jié)果',
         width: 80,
         dataIndex: 'inform_result',
         render: (v) =>
            v === 0 ? (
               <Tag color="#87d068">成功</Tag>
            ) : (
               <Tag color="#f50">失敗</Tag>
            ),
      },
      {
         title: '操作',
         width: 60,
         render: (v, record) => (
            <React.Fragment>
               <a
                  onClick={() => {
                     setModal({
                        action: 'detail',
                        isShow: true,
                        record,
                     });
                  }}
               >
                  詳情
               </a>
            </React.Fragment>
         ),
      },
   ];

   return (
      <React.Fragment>
         <Form layout="inline">
            {DeleteEle}
            {FilterEles}
         </Form>
         <Table
            {...{
               scroll: { x: 1170, y: '70vh' },
               columns,
               dataSource: list || [],
               rowSelection,
               pagination: paginationConfig,
               rowKey: 'inform_uuid',
            }}
         />
         {ModalEle}
      </React.Fragment>
   );
};

export default TestTable;

Hook封裝

usePagination

配置表格的分頁功能

const usePagination = () => {
    // 默認數(shù)據(jù)
  const [pagination, setPagination] = useState({
    page: 1,
    pageSize: 10,
    total: 0,
  });
  // 用于觸發(fā)外層的刷新
  const [pageRefresh, setPageRefresh] = useState(false);

  const config = {
    size: "small",
    showQuickJumper: false,
    total: pagination.total,
    current: pagination.page,
    showSizeChanger: true,
    onChange: (current) => {
      setPagination({
        ...pagination,
        page: current,
      });
      setPageRefresh(() => !pageRefresh); // 修改頁數(shù)后,通知外層刷新
    },
    pageSize: pagination.pageSize,
    onShowSizeChange: (page, pageSize) => {
      setPagination({
        page,
        pageSize,
      });
      setPageRefresh(() => !pageRefresh);// 修改頁碼后,通知外層刷新
    },
  };

  return {
    pagination,
    pageRefresh,
    setPagination,
    paginationConfig: config,
  };
};

useSelect

配置表格的選擇功能

const useSelect = () => {
  const [selectedKeys, setSelectedKeys] = useState([]);
  const rowSelection = {
    onChange: (selectedKeys) => {
      setSelectedKeys(selectedKeys);
    },
    selectedRowKeys: selectedKeys,
  };

  return { selectedKeys, rowSelection, setSelectedKeys };
};

useDelete

配置表格的批量刪除按鈕

const useDelete = ({ url = "", data = {}, success = null, keys = [] }) => {
  const handleDel = () => {
    // 請求..
    message.success("刪除成功");
    success && success();  // 
  };

  const DeleteEle = (
    <React.Fragment>
        { /**OPER.isDelete  : 當有權限時才顯示  */}
      {OPER.isDelete && (
        <Form.Item>
          {keys.length === 0 ? (
            <Button icon={<DeleteOutlined />} size="small" disabled>
              批量刪除
            </Button>
          ) : (
            <Popconfirm
              title="批量刪除"
              description="你確定要刪除嗎?"
              okText="確定"
              cancelText="取消"
              onConfirm={handleDel}
            >
              <Button
                type="primary"
                danger
                icon={<DeleteOutlined />}
                size="small"
              >
                批量刪除
              </Button>
            </Popconfirm>
          )}
        </Form.Item>
      )}
    </React.Fragment>
  );

  return [DeleteEle];
};

useFilter

配置過濾項,附帶查詢、重置按鈕

import { initFilter, getFormItem } from "./utils";  // 根據(jù)配置配置初始化filter數(shù)據(jù) ;  根據(jù)配置獲取組件

const useFilter = (config = []) => {
  const [filter, setFilter] = useState(initFilter(config));
  const [refresh, setRefresh] = useState(false);

 // 重置過濾項
  const handleResetFilter = () => {
    setFilter(initFilter(config));
    setRefresh(!refresh); // 通知外層刷新
  };

  // 觸發(fā)查詢
  const handleSearch = () => {
    setRefresh(!refresh); // 通知外層刷新
  };

 // 修改日期類型
  const handleDateChange = ([startField, endField], [startTime, endTime]) => {
    setFilter({ ...filter, [startField]: startTime, [endField]: endTime });
  };

 // 修改input 類型
  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setFilter({ ...filter, [name]: value });
  };

// 修改select 類型
  const handleSelectChange = (name, value) => {
    setFilter({ ...filter, [name]: value });
  };


 // 根據(jù)配置生成表單項
  const FormItemEles = getFormItem(config, {
    filter,
    handleInputChange,
    handleSelectChange,
    handleDateChange,
  });
 

  const HandlerEles = [
    <Form.Item>
      <Button
        type="primary"
        size="small"
        onClick={handleSearch}
        icon={<SearchOutlined />}
      >
        查詢
      </Button>
    </Form.Item>,
    <Form.Item>
      <Button
        type="primary"
        size="small"
        onClick={handleResetFilter}
        icon={<ReloadOutlined />}
      >
        重置
      </Button>
    </Form.Item>,
  ];

  return {
    filter,
    FilterEles: [...FormItemEles, ...HandlerEles],
    filterRefresh: refresh,
  };
};

initFilter:根據(jù)不同類型初始化filter數(shù)據(jù)

const initFilter = (arr) => {
  const obj = {};
  arr.forEach((item) => {
    switch (item.type) {
      case "inputString":
        obj[item.name] = item.initValue || "";
        break;
      case "select":
        obj[item.name] = item.initValue || 0;
        break;
      case "dateRange":
        item.name.forEach((name) => {
          obj[name] = "";
        });
        break;
      default:
        break;
    }
  });

  return obj;
};

getFormItem:根據(jù)不同的類型生成表單項組件

const getFormItem = (
  arr,
  { filter, handleInputChange, handleSelectChange, handleDateChange }
) => {
  const Eles = [];
  arr.forEach((item) => {
    const name = item.name;
    const label = item.label;
    const value = filter[name];
    switch (item.type) {
      case "inputString":
        Eles.push(
          <Form.Item>
            <Input
              size="small"
              placeholder={label}
              name={name}
              value={value}
              onChange={handleInputChange}
            />
          </Form.Item>
        );
        break;
      case "select":
        Eles.push(
          <Form.Item>
            <Select
              size="small"
              style={{ width: 120 }}
              onChange={(v) => {
                handleSelectChange(name, v);
              }}
              name={name}
              value={value}
              options={item.options}
            />
          </Form.Item>
        );
        break;
      case "dateRange":
        Eles.push(
          <Form.Item>
            <RangePicker
              onChange={(dates) => {
                handleDateChange(name, dates);
              }}
              value={[filter[name[0]], filter[name[1]]]}
              placeholder={label}
              size="small"
            />
          </Form.Item>
        );
      default:
        break;
    }
  });

  return Eles;
};

useModal

配置模態(tài)框

const useModal = (
  config = [
    {
      title: "詳情",
      action: "detail",
      getComponent: (record)=><div>詳情</div>,
    },
  ]
) => {
  const [modal, setModal] = useState({
    isShow: false,
    record: null,
    action: "",
  });
  const handleCancel = () => {
    setModal({
      isShow: false,
      record: null,
      action: "",
    });
  };

  //對話框信息
  let modalProps = {
    open: modal.isShow,
    onCancel: handleCancel,
    maskClosable: false,
    footer: null,
  };

  const currentModal = config.find((item) => item.action === modal.action); // 找到當前模態(tài)框數(shù)據(jù)
  if (currentModal) {
    const { action, getComponent, ...other } = currentModal;
    // 配置傳進來的其余屬性
    modalProps = {
      ...modalProps,
      ...other,
    };
  }

  const ModalEle = (
    <Modal width="80%" {...modalProps}>
      {currentModal && currentModal.getComponent(modal.record)}
    </Modal>
  );

  return { ModalEle, modal, setModal };
};

源碼

github

以上就是React通過hook實現(xiàn)封裝表格常用功能的詳細內(nèi)容,更多關于React hook封裝表格常用功能的資料請關注腳本之家其它相關文章!

相關文章

  • React報錯Too many re-renders解決

    React報錯Too many re-renders解決

    這篇文章主要為大家介紹了React報錯Too many re-renders解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 如何在React中直接使用Redux

    如何在React中直接使用Redux

    這篇文章主要介紹了如何在React中直接使用Redux,目前redux在react中使用是最多的,所以我們需要將之前編寫的redux代碼,融入到react當中去,本文給大家詳細講解,需要的朋友可以參考下
    2022-11-11
  • 在react中使用windicss的問題

    在react中使用windicss的問題

    這篇文章主要介紹了在react中使用windicss的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • React超詳細分析useState與useReducer源碼

    React超詳細分析useState與useReducer源碼

    我正在處理的組件是表單的時間輸入。表單相對復雜,并且是動態(tài)生成的,根據(jù)嵌套在其他數(shù)據(jù)中的數(shù)據(jù)顯示不同的字段。我正在用useReducer管理表單的狀態(tài),到目前為止效果很好
    2022-11-11
  • react實現(xiàn)導航欄二級聯(lián)動

    react實現(xiàn)導航欄二級聯(lián)動

    這篇文章主要為大家詳細介紹了react實現(xiàn)導航欄二級聯(lián)動,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • react中代碼塊輸出,代碼高亮顯示,帶行號,能復制的問題

    react中代碼塊輸出,代碼高亮顯示,帶行號,能復制的問題

    這篇文章主要介紹了react中代碼塊輸出,代碼高亮顯示,帶行號,能復制的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Remix如何支持原生?CSS方法詳解

    Remix如何支持原生?CSS方法詳解

    這篇文章主要為大家介紹了Remix如何支持原生CSS的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • React如何配置src根目錄@

    React如何配置src根目錄@

    這篇文章主要介紹了React如何配置src根目錄@,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-01-01
  • React中Portals與錯誤邊界處理實現(xiàn)

    React中Portals與錯誤邊界處理實現(xiàn)

    本文主要介紹了React中Portals與錯誤邊界處理實現(xiàn),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • ahooks?useInfiniteScroll源碼解析

    ahooks?useInfiniteScroll源碼解析

    這篇文章主要為大家介紹了ahooks?useInfiniteScroll源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01

最新評論