最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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: ['開始日期', '結束日期'],
         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: '通知結果',
         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封裝表格常用功能的資料請關注腳本之家其它相關文章!

相關文章

  • 一百多行代碼實現(xiàn)react拖拽hooks

    一百多行代碼實現(xiàn)react拖拽hooks

    這篇文章主要介紹了一百多行代碼實現(xiàn)react拖拽hooks,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • React組件設計模式之組合組件應用實例分析

    React組件設計模式之組合組件應用實例分析

    這篇文章主要介紹了React組件設計模式之組合組件,結合實例形式分析了React組件設計模式中組合組件相關概念、原理、應用場景與操作注意事項,需要的朋友可以參考下
    2020-04-04
  • 從閉包陷阱到內(nèi)存泄漏解析React Hooks避坑指南

    從閉包陷阱到內(nèi)存泄漏解析React Hooks避坑指南

    這篇文中主要從閉包陷阱到依賴地獄,從無限循環(huán)到內(nèi)存泄漏,為大家簡單盤點一下React Hooks中的常見避坑方法,文中的示例代碼講解詳細,希望對大家有所幫助
    2026-03-03
  • React+ts實現(xiàn)二級聯(lián)動效果

    React+ts實現(xiàn)二級聯(lián)動效果

    這篇文章主要為大家詳細介紹了React+ts實現(xiàn)二級聯(lián)動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • webpack構建react多頁面應用詳解

    webpack構建react多頁面應用詳解

    這篇文章主要介紹了webpack構建react多頁面應用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 插件化機制優(yōu)雅封裝你的hook請求使用方式

    插件化機制優(yōu)雅封裝你的hook請求使用方式

    這篇文章主要為大家介紹了插件化機制優(yōu)雅封裝你的hook請求使用方式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • React?JSX深入淺出理解

    React?JSX深入淺出理解

    React使用JSX來替代常規(guī)的JavaScript。JSX是一個看起來很像 XML的JavaScript語法擴展。我們不需要一定使用 JSX,但它有以下優(yōu)點:JSX執(zhí)行更快,因為它在編譯為JavaScript代碼后進行了優(yōu)化。它是類型安全的,在編譯過程中就能發(fā)現(xiàn)錯誤。使用JSX編寫模板更加簡單快速
    2022-12-12
  • React報錯Too many re-renders解決

    React報錯Too many re-renders解決

    這篇文章主要為大家介紹了React報錯Too many re-renders解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • react遞歸組件實現(xiàn)樹的示例詳解

    react遞歸組件實現(xiàn)樹的示例詳解

    在一些react項目中,常常有一些需要目錄樹這種結構,這篇文章主要為大家介紹了如何使用遞歸組件實現(xiàn)樹,感興趣的小伙伴可以了解下
    2024-10-10
  • 基于React實現(xiàn)下拉刷新效果

    基于React實現(xiàn)下拉刷新效果

    這篇文章主要介紹了如何基于react實現(xiàn)下拉刷新效果,在下拉的時候會進入loading狀態(tài),文中有詳細的代碼示例供大家參考,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03

最新評論

崇信县| 岳池县| 绥棱县| 六盘水市| 涡阳县| 屏东市| 西乡县| 阜新市| 耒阳市| 视频| 砀山县| 勐海县| 故城县| 珲春市| 灵台县| 高要市| 娄底市| 滕州市| 连云港市| 玉山县| 西林县| 开平市| 奉新县| 新民市| 敦煌市| 尚义县| 黎川县| 剑河县| 余姚市| 丹江口市| 宁波市| 大英县| 三原县| 宁波市| 洱源县| 肃南| 和顺县| 大英县| 防城港市| 东兰县| 栖霞市|