首页 > 其他分享 >React+AntD Table支持下拉分页和自定义输入分页条数

React+AntD Table支持下拉分页和自定义输入分页条数

时间:2024-11-20 10:43:22浏览次数:1  
标签:const 分页 自定义 Bus param React .. import pageSize

实例

支持在下拉分页框内输入分页条数来实现自定义分页

代码

  • usePageSizeSelect.js
import {useEffect, useState} from "react";
import Bus from "../../utils/eventBus";

export function usePageSizeSelect() {
    const onInputKeyDown = (e) => {
        const tempVal = e.target.value;
        if (String(e.key) === 'Enter') {
            console.log('output-> key', e.target.value)
            setVal(e.target.value)
            let totalOptions = [
                ...pageOptions,
                {
                    value: `${tempVal}`,
                    label: `${tempVal}条/页`
                }
            ]
            totalOptions.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
            setPageOptions(totalOptions)
            Bus.emit('handle-page-size-change', {pageSize: tempVal})
        }
    }
    const handleSelect = (val, option) => {
        setVal(val)
        Bus.emit('handle-page-size-change', {pageSize: val})
    }
    useEffect(() => {
        const resetPageOptionListener = () => {
            setVal('8')
        }
        Bus.addListener('reset-page-option', resetPageOptionListener)

        return () => {
            Bus.removeListener('reset-page-option', resetPageOptionListener)
        }
    }, []);
    const [val, setVal] = useState('8')
    const [pageOptions, setPageOptions] = useState(
        [
            {
                value: '8',
                label: '8条/页',
            },
            {
                value: '32',
                label: '32条/页',
            },
            {
                value: '64',
                label: '64条/页',
            },
            {
                value: '128',
                label: '128条/页',
            },
            {
                value: '768',
                label: '768条/页',
            },
            {
                value: '1024',
                label: '1024条/页',
            },
        ]
    )
    return {
        onInputKeyDown,
        val,
        setVal,
        pageOptions,
        handleSelect
    }
}

  • PageSizeSelect.tsx
import { Select } from 'antd';
import React from 'react';
import {usePageSizeSelect} from "../../../hooks/keyMan/usePageSizeSelect";

const PageSizeSelect = () => {
    const {
        val,
        setVal,
        onInputKeyDown,
        pageOptions,
        handleSelect
    } = usePageSizeSelect()


    return(
        <Select
            className="page-size-selector"
            allowClear
            showSearch
            defaultValue="8"
            size={'small'}
            style={{ width: 160, marginBottom: 0, border: '2px solid #45526d', lineHeight: 0}}
            placeholder="请输入分页数"
            getPopupContainer={((triggerNode: any) => triggerNode.parentElement) as any}
            value={val}
            optionFilterProp="label"
            onInputKeyDown={e=> onInputKeyDown(e)}
            options={pageOptions}
            onSelect={handleSelect}
        />
    )
}

export default PageSizeSelect;

  • PageSizeSelect结合Table和Pagination组件使用
import React, {useEffect, useRef} from "react";
import keyManComStyl from "./KeyManComponent.styl";
import batchConcern from "../../assets/keyman/batchConcern.svg";
import batchSubscribe from "../../assets/keyman/batchSubscribe.svg";
import {ADD_CONTROL_COLS} from "../../utils/bean";
import {useKeyManTable} from "../../hooks/keyMan/layout/useKeyManTable";
import FilterBtnBox from "./FilterBtnBox";
import {message, Pagination, Popconfirm, Table} from "antd";
import BatchSubscribe from "../../pages/main/subscription/BatchSubscribe";
import SubscriberStore from "src/stores/modules/SubscriberStore";
import Bus from "../../utils/eventBus";
import PageSizeSelect from "./table/PageSizeSelect";
import EditKeyMan from "./modal/EditKeyMan";
import {useEditKeyMan} from "../../hooks/keyMan/useEditKeyMan";
import AllSubscribe from "../../pages/main/subscription/AllSubscribe";

const KeyManTable = ({treeType, curSourceUnit}) => {
    const {
        rowSelection,
        pageNo,
        setPageNo,
        pageSize,
        setPageSize,
        searchData,
        pageTotal,
        onPaging,
        onPagingSizeChange,
        dataSource,
        loading,
        loadTableData,
        onBatchFocus,
        onBatchCancelFocus,
        selectedTableKeys,
        selectedTableRows,
        setSelectedTableKeys,
        setSelectedTableRows,
    } = useKeyManTable()

    const batchSubRef = useRef(null)
    const allSubscribeRef = useRef(null)

    const onShowBatchModalListener = (record:any) => {
        SubscriberStore.setSubscribers([record]) // cache selected row
        if (batchSubRef?.current) {
            batchSubRef.current.showModal()
        }
    }
    const resetSelectedTableData = () => {
        SubscriberStore.setSubscribers([])
        setSelectedTableKeys([])
        setSelectedTableRows([])
    }
    const handlePageSizeSelect = ({pageSize}) => {
        setPageNo(1)
        setPageSize(pageSize)
        onPagingSizeChange(1, pageSize)
    }
    const {
        editKeyManRef,
        onShowEditKeyMan,
    } = useEditKeyMan()
    useEffect(() => {
        Bus.addListener('reset-selected-tableData', resetSelectedTableData)
        Bus.addListener('subscribe-modal-show', onShowBatchModalListener)
        Bus.addListener('handle-page-size-change', handlePageSizeSelect)
        Bus.addListener('edit-key-man-show', onShowEditKeyMan)
        return () => {
            Bus.removeListener('reset-selected-tableData', resetSelectedTableData)
            Bus.removeListener('subscribe-modal-show', onShowBatchModalListener)
        }
    }, []);
    return (
        <>
            <section className={keyManComStyl["key-man-table"]}>
                <div className="table-box custom-table-box">
                    <Table
                        scroll={{y: '380px'}}
                        rowSelection={{
                            type: 'checkbox',
                            ...rowSelection
                        }}
                        size={"small"}
                        rowKey={record => record.id}
                        dataSource={dataSource}
                        columns={ADD_CONTROL_COLS}
                        pagination={false}
                        loading={loading}
                    />
                    <div style={{display: 'flex', justifyContent: 'flex-end', alignItems: 'center'}}>
                        <span>
                            <Pagination
                                current={pageNo}
                                pageSize={pageSize}
                                total={pageTotal}
                                showQuickJumper
                                onChange={onPaging}
                                showSizeChanger={false}
                                // onShowSizeChange={onPagingSizeChange}
                                showTotal={total => `共 ${total} 条`}
                            />
                        </span>
                        <span className="page-size-select-box" style={{ marginLeft: '14px'}}>
                            <PageSizeSelect/>
                        </span>
                    </div>
                </div>
            </section>
        </>
    );
};

export default KeyManTable


  • useKeymanTable.js 表格相关逻辑抽取
import {useEffect, useState} from "react";
import NewBaseDataService from 'src/services/baseData/newIndex'
import Bus from "../../../utils/eventBus";
import KeyManTableStore from "src/stores/modules/keyManTable";
import {message} from "antd";
import KeyManServices from "src/services/keyMan";
import {unique} from "../../../utils/bean";
export function useKeyManTable() {
    const [pageNo, setPageNo] = useState(1);
    const [pageSize, setPageSize] = useState(8);
    const [pageTotal, setPageTotal] = useState(0);
    const [dataSource, setDataSource] = useState([])
    const [loading, setLoading] = useState(false)
    const [searchData, setSearchData] = useState({
        pageNo,
        pageSize,
        dataSource: '',
        sourceUnit: '',
        businessLabel: '',
        belongingPlace: '',
        businessLabelRule: 'or',
        belongingPlaceRule: 'or'
    })
    const [cacheSearchData, setCacheSearchData] = useState({})
    const onPaging = (page) => {
        setPageNo(page)
        setPageSize(pageSize)
        setSearchData({
            ...searchData,
            pageNo: page,
        })
        Bus.emit('on-paging-by-filter', {pageNo: page, pageSize})
        // loadTableData({pageNo: page, pageSize}, true).then(r => r)
    }

    const onPagingSizeChange = (page, pageSize) => {
        Bus.emit('on-paging-by-filter', {pageNo: page, pageSize})
        // loadTableData({pageNo: page, pageSize}, true).then(r => r)
        setPageNo(page)
        setPageSize(pageSize)
    }
    const [selectedTableKeys, setSelectedTableKeys] = useState([])
    const [selectedTableRows, setSelectedTableRows] = useState([])
    // 选中的行 去空,去重
    const selectedRowsUnique = (list = []) => {
        const rows = list.filter(Boolean)
        return unique([...selectedTableRows, ...rows])
    }

    // 点击取消/选中 单行  用户手动选择/取消选择某行的回调
    const onSelectRow = (record, selected, selectedRows) => {
        const newRows = selectedRowsUnique(selectedRows)
        const arr = newRows.filter(item => {
            if (item.id === record.id) {
                return selected
            }
            return true
        })
        setSelectedTableRows(arr)
        setSelectedTableKeys(arr.map(item => item.id))
    }

    // 点击取消/选中 一页的所有  用户手动选择/取消选择所有行的回调
    const onSelectAllRow = (selected, selectedRows, changeRows) => {
        let newRows = selectedRowsUnique(selectedRows)
        if (!selected) {
            const arr = changeRows.map(item => item.id)
            newRows = newRows.filter(item => !arr.includes(item.id))
        }
        setSelectedTableRows(newRows)
        setSelectedTableKeys(newRows.map(item => item.id))
    }
    // 选中项发生变化时的回调
    // const onChange = (selectedRowKeys, selectedRows, info) => {
    // }
    const rowSelection = {
        // onChange: onChange,
        onSelect: onSelectRow,
        onSelectAll: onSelectAllRow,
        getCheckboxProps: (record) => ({
            disabled: record.name === 'Disabled User', name: record.name,
        }), selectedRowKeys: selectedTableKeys
    };

    const loadTableData = async (param = {}, isCache = false) => {
        let payload = {
            ...searchData,
            ...param
        }
        if(isCache) {
            let cacheData = KeyManTableStore.getCacheSearchParam()
                payload = {
                    ...param,
                    dataSource: cacheData.dataSource,
                    sourceUnit: cacheData.sourceUnit,
                    focus: cacheData.focus,
                }
        }
        KeyManTableStore.setCacheSearchParam(payload)
        setLoading(true)
        const res = await NewBaseDataService.getKeyPersons(payload);
        if (res.status === 200) {
            setLoading(false)
            setDataSource(res.data)
            setPageTotal(res.total)
            setLoading(false)
        }
    }
    const onPagingFromFilter = () => {
        const curPagingListener = (payload) => {
            let param = {
                ...payload,
            }
            loadTableData(param, true).then(r => r)
        }
        Bus.addListener('filter-table-data-with-cur-paging', curPagingListener)
        return curPagingListener
    }
    const panelFilterListener = () => {
        const filterTableDataListener = (payload) => {
            let param = {
                ...searchData, ...payload
            }
            loadTableData(param, true).then(r => r)
        }
        Bus.addListener('filter-table-data', )
    }

    // 其他:dataSource: 0( when dataSource === 0 => sourceUnit)
    const treeFilterListener = () => {
        const treeFilterTableDataListener = (payload) => {
            setPageNo(1)
            setSearchData({
                ...searchData,
                pageNo: 1,
                pageSize: 8,
                businessLabel: '',
                belongingPlace: '',
                businessLabelRule: 'or',
                belongingPlaceRule: 'or',
            })
            let param = {
                ...searchData, ...payload,
            }
            if (param.sourceUnit === 'all') {
                param.sourceUnit = ''
                param.dataSource = ''
                param.businessLabelRule = 'or'
                param.belongingPlaceRule = 'or'
            }


            loadTableData(param).then(r => r)
        }
        Bus.addListener('tree-filter-table-data', treeFilterTableDataListener)
        return treeFilterTableDataListener
    }
    useEffect(() => {
        loadTableData().then(r => r)
        const filterTableDataListener = (payload) => {
            let param = {
                ...searchData, ...payload
            }
            loadTableData(param, true).then(r => r)
        }
        Bus.addListener('filter-table-data', filterTableDataListener)
        const treeFilterTableDataListener = treeFilterListener()
        const fromFilterListener = onPagingFromFilter()
        const commonTableDataListener = () => {
            loadTableData({}, true).then(r => r)
            setSelectedTableRows([])
            setSelectedTableKeys([])
        }
        Bus.addListener('common-table-data', commonTableDataListener)
        Bus.addListener('reset-paging', resetSearchParam)
        return () => {
            console.log('output-> 【UnMount】', )
            Bus.removeListener('reset-paging', resetSearchParam)
            Bus.removeListener('common-table-data', commonTableDataListener)
            Bus.removeListener('tree-filter-table-data', treeFilterTableDataListener)
            Bus.removeListener('filter-table-data', filterTableDataListener)
            Bus.removeListener('filter-table-data-with-cur-paging', fromFilterListener)
        }
    }, [])

    // 筛选
    const handleFilter = () => {
        setLoading(true)
        // loadTableData()
    }
    // 简单筛选
    const handleSimpleFilter = () => {
    }

    // 重置
    const resetSearchParam = () => {
        setPageNo(1)
        setPageSize(8)
        Bus.emit('reset-page-option')
    }

    // 批量关注
    const onBatchFocus = async () => {
        if(!selectedTableKeys.length) {
            message.warn('请选择待关注人')
            return
        }
        const res = await KeyManServices.batchKeyManFocus(selectedTableKeys)
        if(res.status === 200) {
            setSelectedTableKeys([])
            await loadTableData({}, true)
            Bus.emit('refresh-left-tree')
            message.success('操作成功')
        }
    }

    // 批量取消关注
    const onBatchCancelFocus = async () => {
        if(!selectedTableKeys.length) {
            message.warn('请选择待取消关注人')
            return
        }
        const res = await KeyManServices.batchCancelConcern(
            selectedTableKeys
        )
        if(res.status === 200) {
            setSelectedTableKeys([])
            await loadTableData({focus: 1})
            Bus.emit('refresh-left-tree')
            message.success('操作成功')
        }
    }
    return {
        pageNo,
        setPageNo,
        pageSize,
        setPageSize,
        pageTotal,
        searchData,
        setSearchData,
        onPaging,
        rowSelection,
        dataSource,
        handleFilter,
        loading,
        selectedTableKeys,
        selectedTableRows,
        loadTableData,
        onPagingSizeChange,
        onBatchFocus,
        onBatchCancelFocus,
        setSelectedTableKeys,
        setSelectedTableRows,
    }
}

标签:const,分页,自定义,Bus,param,React,..,import,pageSize
From: https://www.cnblogs.com/openmind-ink/p/18556366

相关文章

  • React+AntD文件上传并自定义上传逻辑
    上传组件DragClickUpload.tsximport{CloudUploadOutlined}from'@ant-design/icons';importtype{UploadProps}from'antd';import{message,Upload}from'antd';importReact,{useState}from'react';importaxiosfrom&......
  • reactflow 中 useOnViewportChange 模块作用
    1.响应视口变化的核心功能在ReactFlow中,`useOnViewportChange`是一个用于处理视口(Viewport)变化的钩子。视口是用户在界面上看到的包含流程图部分的区域,它的变化包括但不限于平移、缩放、旋转等操作。这个模块的主要作用是让开发者能够监听和响应视口的这些变化。2.执行......
  • reactflow 中 useReactFlow 模块作用
    1.访问ReactFlow核心实例和状态它允许组件访问ReactFlow的核心实例及其相关状态。这意味着组件可以获取到有关整个流程图的关键信息,例如当前的缩放级别、视口的位置和大小等。2.操作ReactFlow实例方法除了获取状态,`useReactFlow`还提供了操作ReactFlow实例方法的......
  • 使用脚手架搭建React项目
    ​......
  • React 组件中 State 的定义、使用及正确更新方式
    ​......
  • Ingress nginx自定义错误页面
     Ingressnginx自定义错误页面的深度定制1、错误页面状态码网站运行过程中难免出现问题,为用户抛出一个错误页面,常见的错误页面包含403、404、500、502、503、504状态码,这些常见的错误页面状态码的含义如下403Forbidden404NotFound500InternalServerEroor502......
  • 将打包后的 React或Vue 与 WebApi 部署在同一站点
    前后端分离的开发中,在部署项目时通常会分开进行部署,而这样又很麻烦,需要配置跨域,域名配置等等有一些情景下,我们需要采用更为方便的方式去部署,可以参考下方方法进行调整准备WebApi项目一个打包好的前端项目React或VUE都可以调整为WebApi项目新增wwwroot文件夹,用于放置前......
  • RedMine自定义--新增复制问题标题和链接按钮
    前言:Redmine本身的复制链接按钮只能复制问题的链接详情,复制出来的格式是:ip.xxxx/issues/200  这次自定义出来一个按钮,希望可以复制问题的标题和链接,这样发送问题给别人时能先知道这个问题大概是什么 一:首先找到redmine菜单栏的代码路径,在:redmine/app/views/issues的_action......
  • Taro首个支持鸿蒙的 UI 库,同时还兼容 React Native、小程序、H5
    Taro4.0已经推出一段时间了,4.0版本主要是支持了鸿蒙端的开发以及Vite编译工具的支持。duxapp在这段时间也跟随Taro的脚步,实现的对鸿蒙端的支持,并且也将之前的duxui这个多端的UI库,对鸿蒙端实现了兼容。duxui组件库提供了60+的组件支持,能快速帮助你完成业务。现在......
  • Jmeter进行IP欺骗,使用自定义 HTTP Header 设置 IP 地址
     1、创建ips.txt文件,在里面写入局域网中没有被使用的ip地址;添加线程组  2、在线程组里加入‘CSV数据文件设置’,填上ips.txt文件 3、在线程组里加入HTTP信息头管理器,加入请求头X-Forwarded-For,值写‘CSV数据文件设置’中的‘变量名称’ 4、在线程组里加入HTTP请求......