欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

封裝內(nèi)容

  • 配置分頁:usePagination
  • 生成過濾項(xiàng):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'; // 模擬請(qǐng)求數(shù)據(jù)
import TableGenerator from '../TableGenerator'; // 封裝的鉤子

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

const TestTable = () => {
   // 1. 生成過濾項(xiàng)。
   // 傳入配置,可以自行擴(kuò)展。目前支持輸入框、日期范圍選擇器、普通選擇器
   // FilterEles:過濾項(xiàng)表單項(xiàng)
   // filterRefresh:暴露出來告訴外層需要重新獲取數(shù)據(jù)了
   const { FilterEles, filter, filterRefresh } = useFilter([
      {
         name: 'name', // 字段
         label: '平臺(tái)名稱', // placeholder
         type: 'inputString', // 組件類型:字符串輸入框
      },
      {
         name: 'status',
         label: '狀態(tài)',
         type: 'select', // 組件類型:選擇器
         initValue: 0, // 默認(rèn)數(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ù)組,用于配置所有彈框類型(詳情、添加、編輯等),目前只支持詳情,可自行擴(kuò)展
   // ModalEle: 模態(tài)框組件
   // modal: {isShow:boolean, action:string, record:any}
   const { ModalEle, modal, setModal } = useModal([
      {
         title: '詳情', // 彈框標(biāo)題
         action: 'detail', // 彈框類型
         getComponent: (record) => <Detail data={record} />, // 彈框數(shù)據(jù)
         // ... 可以繼續(xù)添加屬性,其他屬性將會(huì)應(yīng)用到Modal中 比如footer、handleOk
      },
   ]);

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

   const [list, setList] = useState([]);
   const getList = () => {
      // 請(qǐng)求數(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、點(diǎn)擊查詢、重置時(shí)將會(huì)觸發(fā)
   useEffect(() => {
      getList();
   }, [pageRefresh, filterRefresh]);

   const columns = [
      {
         title: '序號(hào)',
         width: 50,
         align: 'center',
         render: (v, r, index) =>
            index + 1 + (pagination.page - 1) * pagination.pageSize,
      },
      {
         title: '平臺(tái)名稱',
         width: 180,
         dataIndex: 'req_psname',
      },
      {
         title: '請(qǐng)求時(shí)間',
         width: 140,
         dataIndex: 'inform_time',
      },
      {
         title: '通知對(duì)象',
         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 = () => {
    // 默認(rèn)數(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 = () => {
    // 請(qǐng)求..
    message.success("刪除成功");
    success && success();  // 
  };

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

  return [DeleteEle];
};

useFilter

配置過濾項(xiàng),附帶查詢、重置按鈕

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

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

 // 重置過濾項(xiàng)
  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ù)配置生成表單項(xiàng)
  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ù)不同的類型生成表單項(xiàng)組件

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: "",
    });
  };

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

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

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

  return { ModalEle, modal, setModal };
};

源碼

github

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

相關(guān)文章

  • React報(bào)錯(cuò)Too many re-renders解決

    React報(bào)錯(cuò)Too many re-renders解決

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

    如何在React中直接使用Redux

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

    在react中使用windicss的問題

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

    React超詳細(xì)分析useState與useReducer源碼

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

    react實(shí)現(xiàn)導(dǎo)航欄二級(jí)聯(lián)動(dòng)

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

    react中代碼塊輸出,代碼高亮顯示,帶行號(hào),能復(fù)制的問題

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

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

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

    React如何配置src根目錄@

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

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

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

    ahooks?useInfiniteScroll源碼解析

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

最新評(píng)論