react表格排序、显示列等组组件

一:项目效果

二:项目说明

  1. 项目框架

    项目使用 react ant.design

  2. 调用说明

    1.控制是否显示设置,默认true
            1)控制表格列的显示和隐藏
            2)控制列的对齐方式
            3)控制列的排序
    2.控制是否加载,默认false
    3.控制表格是否显示边框,默认true
    4.控制表格的尺寸,默认size为large
    5.rowSelection 控制表格是否显示单选或多选,默认undefined没有选择,非必传

            1)fixed 选择框是否固定
            2)type选择框类型,'checkbox'为多选,type: 'radio'为单选

            3)rowClickSelection 选中的回调
    6.控制分页的位置,默认bottomCenter
    7.控制排序,sortable是true显示,false隐藏,非必传
    8.控制筛选,tableScreen: '税额',筛选字段跟title一至,非必传

    9.过滤,非必传
            1)filterMode: 'tree', // 指定筛选菜单的用户界面 默认menu
            2)filterSearch: true, // 筛选菜单项是否可搜索 false
            3)filterMultiple: true, // 过滤单选,默认为true多选

    10.通用按钮操作 tableButtons 操作按钮,传对象[{title: '按钮名称',event: '按钮事件'}] ,非必传

    备注:

    * 特殊处理按钮 需要遍历后添加render 方法 
    * 切记通用操作按钮和特殊处理按钮二选一

三:组件源码


import React, {useState, useRef} from "react";
import {Button, Input, message, Modal, Select, Switch, Table, Popover} from 'antd';
import styles from "./index.module.less";
import {SettingOutlined} from "@ant-design/icons/lib";
import {useRequest} from "ahooks";
import tableServer from "@/api/XTable";
import {nextTick} from "q";
 
// 接受传参
interface Props {
    pageName: string, // 调用的页面
    showSet?: boolean, // 是否显示设置
    loading?: boolean, // 是否加载
    bordered?: boolean, // 表格是否显示边框
    size?: string, // 表格的尺寸
    rowSelection?: any, // 多选单选
    pagePosition?: string, // 分页的位置
    columns: any, // 列数据
    dataSource: any,// 显示数据
    xTableScreen?: (obj: any) => void, // 筛选的回调
    handleSizeChange?: (obj: any) => void, // 分页的回调
}
 
//查询单选栏
const XTable: React.FC<Props> = (props: any) => {
    const inputDom = useRef() as any
    // 分页的位置 默认右下
    const [pagePosition, setPagePosition] = useState<any>(props.pagePosition || 'bottomCenter')
    // 筛选框输入的值
    const [screenVal, setScreenVal] = useState<any>('')
    // input 输入的记录
    const [screenValRecord, setScreenValRecord] = useState<any>({})
    // 筛选的值
    const [screenLi, setScreenLi] = useState<any>(1)
    // 筛选的值输入的记录
    const [screenLiRecord, setScreenLiRecord] = useState<any>({})
    // 筛选列的值
    const [screenName, setScreenName] = useState<any>('')
    const screens = [
        {
            text: '包含',
            value: 1,
        },
        {
            text: '不包含',
            value: 2,
        },
        {
            text: '等于',
            value: 3,
        },
        {
            text: '不等于',
            value: 4,
        },
        {
            text: '以......开始',
            value: 5,
        },
        {
            text: '以......结束',
            value: 6,
        },
        {
            text: '为空',
            value: 7,
        },
        {
            text: '不为空',
            value: 8,
        }
    ]
    const screenDom = (val: any) => <div>
        <ul className={styles.screenDom}>
            <p><Input
                id={val}
                ref={inputDom}
                placeholder="请输入关键字"
                value={screenVal}
                onClick={
                    (e: any) => {
                        e.stopPropagation()
                    }
                }
                onChange={
                    (e: any) => {
                        e.persist()
                        e.stopPropagation()
                        setScreenVal(e.target.value)
                        // screenValRecord 是否存在 key为val的值
                        const obj = Object.keys(screenValRecord)
                        if (!obj.length) {
                            setScreenValRecord({
                                [val]: e.target.value
                            })
                        } else {
                            const isKey = obj.includes(val)
                            if (isKey) { // 存在
                                screenValRecord[val] = e.target.value
                                setScreenValRecord(screenValRecord)
                            } else {
                                const objs = {[val]: e.target.value}
                                setScreenValRecord({...screenValRecord, ...objs})
                            }
                        }
                    }
                }
            /></p>
            {
                screens.map((item: any, index: number) => {
                    return (
                        <li key={index} className={`${screenLi === item.value ? styles.curr : ''}`}
                            onClick={(e: any) => {
                                e.stopPropagation()
                                setScreenLi(item.value)
                                // screenLiRecord 是否存在 key为val的值
                                const obj = Object.keys(screenLiRecord)
                                if (!obj.length) {
                                    setScreenLiRecord({
                                        [val]: item.value
                                    })
                                } else {
                                    const isKey = obj.includes(val)
                                    if (isKey) { // 存在
                                        screenLiRecord[val] = item.value
                                        setScreenLiRecord(screenLiRecord)
                                    } else {
                                        const objs = {[val]: item.value}
                                        setScreenLiRecord({...screenLiRecord, ...objs})
                                    }
                                }
                                console.log(screenLiRecord, 'screenLiRecord-----')
                            }}>{item.text}</li>
                    )
                })
            }
            <p className={styles.btns}>
                <Button onClick={
                    (e: any) => {
                        e.stopPropagation()
                        setScreenVal('')
                        setScreenLi(1)
                        // 清空记录
                        for (let key in screenValRecord) {
                            if (key === val) {
                                delete screenValRecord[key]
                            }
                        }
                        for (let key1 in screenLiRecord) {
                            if (key1 === val) {
                                delete screenLiRecord[key1]
                            }
                        }
                        setScreenName('')
                        props.xTableScreen({
                            key: screenName,
                            keyWord: screenVal,
                            keyTtitle: screenLi
                        })
                    }
                }>重置</Button>
                <Button type="primary" onClick={
                    (e: any) => {
                        e.stopPropagation()
                        console.log(screenValRecord, 'screenValRecord')
                        if (!screenVal) {
                            message.warning("请输入关键字!");
                            return
                        }
                        props.xTableScreen({
                            key: screenName,
                            keyWord: screenVal,
                            keyTtitle: screenLi
                        })
                        setShowPName('')
                        setVisible(false)
                    }
                }>确定</Button>
            </p>
        </ul>
    </div>
    // 表格列数据
    // 控制点击确定隐藏Popover
    const [showPName, setShowPName] = useState<any>('')
    const [visible, setVisible] = useState<any>('')
    props.columns?.forEach((item: any) => {
        if (item.tableScreen) {
            item.title = (row: any) => {
                return (
                    <Popover
                        overlayClassName={styles.screenTooltip}
                        placement="bottomRight"
                        content={screenDom(item.dataIndex)}
                        trigger='click'
visible={visible && showPName === item.dataIndex}
                        onVisibleChange={
                            console.log(visible)
                                setVisible(visible)
                                if (visible) {
                                    nextTick(() => {
                                        setShowPName(item.dataIndex)
                                        // 设置之前的值
                                        setScreenVal(screenValRecord[item.dataIndex])
                                        setScreenLi(screenLiRecord[item.dataIndex] ? screenLiRecord[item.dataIndex] : 1)
                                        // @ts-ignore
                                        document.getElementById(item.dataIndex).focus()
                                        inputDom.current.focus() // input 自动获取光标
                                        setScreenName(item.dataIndex)
                                    })
                                } else {
                                    setShowPName('')
                                }
                        }
                    >
                        <span className={styles.filterBg} onClick={(e) => {
                            e.stopPropagation()
                        }}>{item.tableScreen}<i></i></span>
                    </Popover>
                )
            }
        }
        // 序号
        // if (item.dataIndex === 'tableNumber') {
        //     item.render = (tx: any, rs: any, idx: any) => idx + 1
        // }
        // 排序
        if (item.sortable) {
            item.sorter = (a: any, b: any) => {
                return (a[item['dataIndex']] - b[item['dataIndex']])
            }
        }
        // 过滤
        if (item.filters && item.filters.length) {
            item.onFilter = (value: string, record: any) => {
                return (
                    record[item.dataIndex].startsWith(value)
                )
            }
        }
        // 操作按钮
        if (item.tableButtons && item.tableButtons.length) {
            item.render = (tx: any, rs: any, idx: any) => (
                item.tableButtons.map((it: any) => {
                    return (
                        <span
                            className={styles.xtableBtns}
                            onClick={(e: any) => {
                                e.stopPropagation()
                                it.event(tx, rs, idx);
                            }}
                        >
                            {it.title}
                        </span>
                    )
                })
            )
        }
    })
 
    const columnsArr = [
        {
            title: '#',
            dataIndex: 'tableNumber',
            width: 60,
            render: (tx: any, rs: any, idx: any) => idx + 1
        }
    ] as any
    props?.columns.forEach((item: any) => {
        if (!item.key) {
            item.key = item.dataIndex
        }
        if (!item.isHide) {
            columnsArr.push(item)
        }
 
    })
    const [columns, setColumns] = useState(columnsArr || [])
    // 表格数据源
    const [dataSource, setDataSource] = useState<any>(props.dataSource || [])
    // 设置表格列表头
    const [columnsLi, setColumnsLi] = useState<any>([
        {
            title: '#',
            dataIndex: 'key',
            key: 'key',
            width: 60,
            render: (text: any, row: any, index: any) => (<span>{index + 1}</span>)
        },
        {
            title: '列名',
            dataIndex: 'name',
            key: 'name',
            width: 150,
            render: (text: any, row: any, index: any) => (<span>{text}</span>)
        },
        {
            title: '对齐方式',
            dataIndex: 'align',
            key: 'align',
            width: 150,
            render: (text: any, row: any, index: any) => (
                <Select
                    defaultValue={row.align ? row.align : 'left'}
                    onChange={(data: any) => {
                        console.log(dataSourceLi, 'dataSourceLi-000')
                        dataSourceLi.forEach((item: any, idx: number) => {
                            if (index === idx) {
                                item.align = data === 'default' ? 'left' : data
                            }
                        })
                        setDataSourceLi(dataSourceLi)
                    }}
                    options={
                        [
                            {
                                value: 'default',
                                label: '默认对齐'
                            },
                            {
                                value: 'left',
                                label: '居左对齐'
                            },
                            {
                                value: 'center',
                                label: '居中对齐'
                            },
                            {
                                value: 'right',
                                label: '居右对齐'
                            }
                        ]
                    }
                />
            )
        },
        {
            title: '隐藏列',
            dataIndex: 'isHide',
            key: 'isHide',
            width: 120,
            render: (text: any, row: any, index: any) => (
                <Switch checked={row.isHide} onChange={(data: any, event: any) => {
                    event.stopPropagation()
                    dataSourceLi.map((item: any, idx: number) => {
                        if (index === idx) {
                            item.isHide = data
                        }
                    })
                    setDataSourceLi([...dataSourceLi])
                }}/>
            )
        }
    ]);
    // 设置表格数据源
    let dataSourceLis = [] as any
    props.columns?.forEach((item: any) => {
        dataSourceLis.push({
            ...item,
            ...{
                name: item.tableScreen ? item.tableScreen : item.title,
                isHide: item.isHide ? item.isHide : false,
            }
        })
    })
    const [dataSourceLi, setDataSourceLi] = useState(dataSourceLis)
 
    // 冻结列
    const [ellipsis, setEllipsis] = useState<any>(false)
    const [yScroll, setYScroll] = useState<any>(false)
    const [xScroll, setXScroll] = useState<string | undefined>('fixed')
    const scroll: { x?: number | string; y?: number | string } = {}
    if (yScroll) {
        scroll.y = 480
    }
    if (xScroll) {
        scroll.x = '100vw - 68'
    }
    const tableColumns = columns.map((item: any) => ({...item, ellipsis}))
    if (xScroll === 'fixed') {
        tableColumns[0].fixed = true
        tableColumns[tableColumns.length - 1].fixed = 'right'
    }
    // 恢复出厂设置
    const recoveryBasic = () => {
        // 发生接口清空缓存数据
        const saveUserWorkPlaceDto = {
            pageName: props.pageName,
            content: '',
            type: 3
        }
        // 清空保存数据
        workPlaceAdd.run(saveUserWorkPlaceDto)
    }
    // 全部显示
    const showHideAll = () => {
        // 切换全部显示和隐藏
        setIsHideAll(!isHideAll)
        // 改变数组的值
        dataSourceLi.map((item: any) => {
            item.isHide = !isHideAll ? true : false
        })
        setDataSourceLi([...dataSourceLi])
    }
    // 置顶
    const topping = () => {
        if (!selectedRows.length) {
            message.warning("请选择需要移动的数据!");
            return
        }
        selectedRows.forEach((item: any) => {
            dataSourceLi.forEach((it: any, index: number) => {
                if (item.name === it.name) {
                    removeArray(dataSourceLi, item)
                    dataSourceLi.splice(0, 0, item)
                }
            })
        })
        setDataSourceLi([...dataSourceLi])
    }
    // 置底
    const bottoming = () => {
        if (!selectedRows.length) {
            message.warning("请选择需要移动的数据!");
            return
        }
        selectedRows.forEach((item: any) => {
            dataSourceLi.forEach((it: any, index: number) => {
                if (item.name === it.name) {
                    removeArray(dataSourceLi, item)
                    dataSourceLi.splice(dataSourceLi.length, 0, item)
                }
            })
        })
        setDataSourceLi([...dataSourceLi])
    }
    // 上移
    const moveUp = () => {
        if (!selectedRows.length) {
            message.warning("请选择需要移动的数据!");
            return
        }
        selectedRows.forEach((item: any) => {
            dataSourceLi.forEach((it: any, index: number) => {
                if (item.name === it.name && index !== 0) {
                    removeArray(dataSourceLi, it)
                    dataSourceLi.splice(index - 1, 0, item)
                }
            })
        })
        setDataSourceLi([...dataSourceLi])
    }
    // 下移
    const moveDown = () => {
        if (!selectedRows.length) {
            message.warning("请选择需要移动的数据!");
            return
        }
        selectedRows.reverse().forEach((item: any) => {
            let found = -1
            dataSourceLi.forEach((it: any, index: number) => {
                if (item.name === it.name && dataSourceLi.length - 1 > index) {
                    removeArray(dataSourceLi, it)
                    found = index
                }
            })
            if (found !== -1) {
                dataSourceLi.splice(found + 1, 0, item)
            }
        })
        setDataSourceLi([...dataSourceLi])
    }
    // xTable表格设置
    const tableProps = {
        loading: props.loading,
        bordered: props.bordered,
        size: props.size,
        scroll,
    };
    // xTable选中的数据
    const [rowKeys, setRowKeys] = useState([]);
    const [rows, setRows] = useState([]);
    const xTableChange = (newSelectedRowKeys: any, row: any) => {
        console.log(newSelectedRowKeys, 'xTable selectedRowKeys changed: ', row);
        setRowKeys(newSelectedRowKeys);
        setRows(row)
        props.rowSelection.rowClickSelection(newSelectedRowKeys, row)
    };
 
    /**
     * 从数组中删除指定对象
     * arrData:数组
     * objData:需删除的对象
     * */
    const removeArray = (arrData: any, objData: any) => {
        let length = arrData.length
        for (let i = 0; i < length; i++) {
            if (arrData[i] === objData) {
                if (i === 0) {
                    arrData.shift() // 删除并返回数组的第一个元素
                    return arrData
                } else if (i === length - 1) {
                    arrData.pop() // 删除并返回数组的最后一个元素
                    return arrData
                } else {
                    arrData.splice(i, 1) // 删除下标为i的元素
                    return arrData
                }
            }
        }
    }
    // 全部显示、隐藏
    const [isHideAll, setIsHideAll] = useState(false);
    // 多选设置
    const [selectedRowKeys, setSelectedRowKeys] = useState([]);
    const [selectedRows, setSelectedRows] = useState([]);
    const onSelectChange = (newSelectedRowKeys: any, row: any) => {
        console.log(newSelectedRowKeys, 'selectedRowKeys changed: ', row);
        setSelectedRowKeys(newSelectedRowKeys);
        setSelectedRows(row)
    };
    // 弹窗设置
    const [isModalOpen, setIsModalOpen] = useState(false);
    const showModal = () => {
        setIsModalOpen(true);
    };
    const handleOk = () => {
        const saveUserWorkPlaceDto = {
            pageName: props.pageName,
            content: JSON.stringify({
                showSet: props.showSet, // 是否显示设置
                loading: props.loading, // 是否加载
                bordered: props.bordered, // 表格是否显示边框
                size: props.size, // 表格的尺寸
                rowSelection: props.rowSelection, // 表格是否可选择
                pagePosition, // 分页的位置
                columns: dataSourceLi // table 设置
            }),
            type: 3
        }
        // 保存数据
        workPlaceAdd.run(saveUserWorkPlaceDto)
    };
    const handleCancel = () => {
        setIsModalOpen(false);
    };
    // 保存设置数据
    const workPlaceAdd = useRequest((data) => tableServer.reqMethod.workPlaceAdd(data), {
        manual: true,
        onSuccess: (result: any) => {
            console.log(result, '---')
            if (result.code === 10200) {
                message.success("设置成功!")
                setIsModalOpen(false);
                // 改变表格显示
                console.log(dataSourceLi, 'dataSourceLi')
                const columnArr = [
                    {
                        title: '#',
                        dataIndex: 'tableNumber',
                        width: 60,
                        render: (tx: any, rs: any, idx: any) => idx + 1
                    }
                ] as any
                dataSourceLi.forEach((item: any) => {
                    if (!item.isHide) {
                        columnArr.push({
                            ...item,
                            ...{
                                align: item.align,
                                fixed: item.fixed
                            }
                        })
                    }
                })
                setColumns(columnArr)
                // 清空选中项
                setSelectedRowKeys([])
                setSelectedRows([])
            } else {
                message.error("设置失败!")
            }
        },
    })
    return (
        <>
            <div className={styles.xTable}>
                <Table
                    {...tableProps}
                    dataSource={dataSource}
                    columns={columns}
                    rowSelection={{
                        fixed: props?.rowSelection?.fixed,
                        type: props?.rowSelection?.type,
                        selectedRowKeys: rowKeys,
                        onChange: xTableChange,
                    }}
                    onRow={
                        (record: any) => {
                            return {
                                onClick: (enevt: any) => {
                                    const rkeys: any = []
                                    let rs: any = []
                                    if (props?.rowSelection?.type === 'radio') {
                                        rkeys.push(record?.id)
                                        rs.push(record)
                                        setRowKeys(rkeys)
                                        setRows(rs)
                                    } else {
                                        let rkeys: any = rowKeys
                                        if (rkeys.length > 0 && rkeys.includes(record?.id)) {
                                            rkeys.splice(rkeys.indexOf(record?.id), 1)
                                        } else {
                                            rkeys.push(record?.id)
                                        }
                                        let rs: any = rows
                                        if (rs.length > 0 && rs.includes(record)) {
                                            rs.splice(rs.indexOf(record), 1)
                                        } else {
                                            rs.push(record)
                                        }
                                        setRowKeys([])
                                        setRows([])
                                        nextTick(() => {
                                            setRowKeys(rkeys)
                                            setRows(rs)
                                            props?.rowSelection?.rowClickSelection(rowKeys, rows)
                                        })
                                    }
                                },
                            }
                        }
                    }
                    pagination={{
                        position: [pagePosition],
                        showSizeChanger: true,
                        showQuickJumper: true,
                        showTotal:(total) => `共 ${total} 条`,
                        // onShowSizeChange: (val, pageSize) => {
                        //     console.log(val, '--2--', pageSize)
                        // },
                        onChange: (val, pageSize) => {
                            console.log(val, '-1---', pageSize)
                            props.handleSizeChange({
                                current: val,
                                pageSize: pageSize
                            })
                        }
                    }}
                />
                {
                    props.showSet ? <div className={styles.set}><SettingOutlined onClick={showModal}/></div> : null
                }
            </div>
            <Modal
                visible={isModalOpen}
                title="列表控制"
                width={716}
                maskClosable={false}
                onOk={handleOk}
                onCancel={handleCancel}
                className={styles.operateBtn}
            >
                <div className={styles.tag}>
                    <span onClick={recoveryBasic}>恢复出厂</span><i>|</i>
                    <span onClick={showHideAll}>全部{isHideAll ? '显示' : '隐藏'}</span><i>|</i>
                    <span onClick={topping}>置顶</span><i>|</i>
                    <span onClick={bottoming}>置底</span><i>|</i>
                    <span onClick={moveUp}>上移</span><i>|</i>
                    <span onClick={moveDown}>下移</span>
                </div>
                <div>
                    <Table
                        dataSource={dataSourceLi}
                        columns={columnsLi}
                        pagination={false}
                        rowSelection={{
                            selectedRowKeys,
                            onChange: onSelectChange,
                        }}
                        scroll={{y: 470}}
                        onRow={record => {
                            return {
                                onClick: event => {
                                    let rowKeys: any = selectedRowKeys
                                    if (rowKeys.length > 0 && rowKeys.includes(record?.dataIndex)) {
                                        rowKeys.splice(rowKeys.indexOf(record?.dataIndex), 1)
                                    } else {
                                        rowKeys.push(record?.dataIndex)
                                    }
                                    let rows: any = selectedRows
                                    if (rows.length > 0 && rows.includes(record)) {
                                        rows.splice(rows.indexOf(record), 1)
                                    } else {
                                        rows.push(record)
                                    }
                                    setSelectedRowKeys([])
                                    setSelectedRows([])
                                    nextTick(() => {
                                        setSelectedRowKeys(rowKeys)
                                        setSelectedRows(rows)
                                    })
                                }, // 点击行
                                onDoubleClick: event => {
                                },
                                onContextMenu: event => {
                                },
                                onMouseEnter: event => {
                                }, // 鼠标移入行
                                onMouseLeave: event => {
                                },
                            };
                        }}
                    />
                </div>
            </Modal>
        </>
    )
}
 
export default XTable

 四:调用源码


// 获取设置数据
useEffect(() => {
    // 获取设置数据
    workPlaceList.run()
}, ['moreSearch'])
 
/*
* 调用说明
* 1.控制是否显示设置,默认true
*     1)控制表格列的显示和隐藏
*     2)控制列的对齐方式
*     3)控制列的排序
* 2.控制是否加载,默认false
* 3.控制表格是否显示边框,默认true
* 4.控制表格的尺寸,默认size为large
* 5.rowSelection 控制表格是否显示单选或多选,默认undefined没有选择,非必传
*   1)fixed 选择框是否固定
*   2)type选择框类型,'checkbox'为多选,type: 'radio'为单选
*   3)rowClickSelection 选中的回调
* 6.控制分页的位置,默认bottomCenter
* 7.控制排序,sortable是true显示,false隐藏,非必传
* 8.控制筛选,tableScreen: '税额',筛选字段跟title一至,非必传
* 9.过滤,非必传
*    1)filterMode: 'tree', // 指定筛选菜单的用户界面 默认menu
*    2)filterSearch: true, // 筛选菜单项是否可搜索 false
*    3)filterMultiple: true, // 过滤单选,默认为true多选
*
*
*
* 10.tableButtons 操作按钮,传对象[{title: '按钮名称',event: '按钮事件'}] ,非必传
*
* */
// TABLE数据
 const dataSource = [
  {
    id: '1',
    key: '1',
    name: '胡彦斌',
    sex: '男',
    address: '西湖区湖底公园1号',
  },
  {
    id: '2',
    key: '2',
    name: '胡彦祖',
    sex: '女',
    address: '西湖区湖底公园1号',
  },
]
 
 
//默认columns
const tableColumns = [
    {
  title: '姓名',
  dataIndex: 'name',
  fixed: 'left',
  sortable: true, // 排序
  tableScreen: '姓名', // 筛选字段跟title对应
  isHide: false, // 隐藏列
  /!*过滤三件套*!/
  filterMode: 'tree', // 指定筛选菜单的用户界面 默认menu
  filterSearch: true, // 筛选菜单项是否可搜索 false
  filterMultiple: true, // 过滤单选,默认为true多选
  filters: [
    {
      text: '胡彦斌',
      value: '胡彦斌',
    },
    {
      text: '胡彦祖',
      value: '胡彦祖',
    },
  ]
},
{
  title: "性别",
  dataIndex: "sex",
  sortable: true,
  /!*过滤三件套*!/
  filterMode: 'tree', // 指定过滤菜单的用户界面 默认menu
  filterSearch: true, // 过滤菜单项是否可搜索 false
  filterMultiple: false, // 过滤 单选,默认为true多选
  filters: [
    {
      text: '男',
      value: '男',
    },
    {
      text: '女',
      value: '女',
    }
  ], // 过滤数据
  tableScreen: '性别' // 筛选字段跟title对应
},
{
  title: "操作",
  dataIndex: 'operation',
  fixed: "right",
  // 通用操作按钮
  tableButtons: [
    {
      title: '详情',
      event: handleInvoiceDetail
    },
    {
      title: '删除',
      event: deleteColumns
    }
  ],
  // 特殊处理按钮 *切记通用操作按钮特殊处理按钮二选一
  render: (text: any, record: any, index: any) => (
    <span>
    {}
      <Button
         type="text"
         style={{ color: "#5B72BE" }}
         onClick={() => {
           handleInvoiceDetail(text, record, index);
         }}
      >
        详情2
      </Button>
      <Button
        type="text"
        style={{ color: "#5B72BE" }}
        onClick={() => deleteColumns(record)}
      >
        删除3
      </Button>
    </span>
   )
  }
] as any;
 
 
// 请求设置数据
const workPlaceList = useRequest((str: string) => tableServer.reqMethod.workPlaceList({ pageName: str, type: 3 }),
    {
      manual: true,
      onSuccess: (result: any) => {
        // 清空数据
        setXColumns([])
        setDispose({})
          const data = result.data && result.data[0]
          if (!data || !data.content) { // 接口没有设置数据, 默认设置
            const columnsDefault = tableColumns
            setXColumns(columnsDefault)
             setDispose({
                 showSet: true, // 是否显示设置
                 loading: false, // 是否加载
                 bordered: true, // 表格是否显示边框
                 size: 'large', // 表格的尺寸
                 rowSelection: {  // 值为 undefined 没有多选跟单选
                    fixed: 'left',
                    type: 'checkbox', // 多选还是单选
                     rowClickSelection, // 选中的回调
                 }, // 表格是否可选择
                 pagePosition: 'bottomCenter', // 分页的位置
             })
          } else {
            const content = JSON.parse(data.content)
            setXColumns(content.columns)
            // 特殊处理按钮需要添加render
            content.columns.forEach((item: any) => {
              if (item.dataIndex === 'operation' && !item.tableButtons) {
               item.render = (text: any, record: any, index: any) => (
                 <span>
                 {}
                  <Button
                    type="text"
                    style={{ color: "#5B72BE" }}
                    onClick={() => {
                      handleInvoiceDetail(text, record, index);
                    }}
                 >
                  详情2
                </Button>
                <Button
                  type="text"
                  style={{ color: "#5B72BE" }}
                  onClick={() => deleteColumns(record)}
               >
                 删除3
               </Button>
             </span>
           )
         }
       })
 
            setDispose({
                 showSet: content.showSet? content.showSet : true, // 是否显示设置
                 loading: content.loading ? content.loading : false, // 是否加载
                 bordered: content.bordered ? content.bordered : true, // 表格是否显示边框
                 size: content.size ? content.size : 'large', // 表格的尺寸
                 rowSelection: content.rowSelection ? content.rowSelection : {
                   fixed: 'left',
                   type: 'checkbox', // 多选还是单选
                   rowClickSelection, // 选中的回调
                 }, // 表格是否可选择
                 pagePosition: content.pagePosition ? content.pagePosition : 'bottomCenter', // 分页的位置
            })
          }
      }
    }
);
 
// xtable 选中的数据
const rowClickSelection = (rowKeys: any, rows: any) => {
  console.log(`rowKeys=: `,rowKeys, 'rows=: ', rows);
}
 
// 对应的按钮操作
const handleInvoiceDetail = (text: any, record: any, index: any) => {
  console.log('对应的按钮操作')
};
 
// 删除弹框
const deleteColumns = (record: any) => {
   console.log('对应的按钮操作')
};
 
// html 调用
{
  xcolumns.length ? <XTable
      dataSource={tableColumns}
      columns={xcolumns}
      {...dispose}
      pageName={pageName}
      xTableScreen={
        (val: any) => {
          console.log('11122', val)
        }
      }
        handleSizeChange={
            (val: any) => {
                console.log('11122', val)
            }
        }
  /> : null
}

五:源码样式 


/*设置*/
.xTable {
  position: relative;
  .set {
    text-align: center;
    line-height: 48px;
    height: 47px;
    width: 48px;
    position: absolute;
    right: 1px;
    top: 1px;
    z-index: 999;
    border-left: 1px solid #E9EEF2;
    background: #F4F6FA;
    border-radius: 0 6px 0 0;
    cursor: pointer;
    opacity: .8;
    &:hover {
      opacity: 1;
    }
    &.curr {
      top: 60px;
    }
  }
}
/*筛选*/
.filterBg {
  i {
    width: 20px;
    height: 20px;
    display: inline-block;
    background: url("../../assets/img/system/filter-fill.png") center center no-repeat;
    background-size: 12px auto;
    opacity: 0.8;
    margin-left: 8px;
    position: relative;
    top: -1px;
    vertical-align: middle;
    &:hover {
      opacity: 1;
    }
  }
}
  .screenDom {
    .btns {
      button {
        &:first-child {
          margin-right: 10px;
        }
      }
    }
    li {
      &:nth-child(2) {
        margin-top: 10px;
      }
      &:nth-last-child(2){
        margin-bottom: 10px;
      }
      line-height: 32px;
      cursor: pointer;
      border-radius: 4px;
      padding-left: 10px;
      color: #353739;
      &.curr {
        color: #306DF6;
        background: rgba(48,109,246,0.1);
        &:hover {
          background: rgba(48,109,246,0.1);
        }
      }
      &:hover {
        background: #F4F6FA;
      }
    }
  }
/*set 弹窗*/
.operateBtn {
  padding-bottom: 10px;
  .tag {
    text-align: right;
    padding-bottom: 12px;
    cursor: pointer;
    color: #306DF6;
    font-size: 14px;
    position: relative;
    top: -5px;
    > span {
      &:hover {
        color: #6896FF;
      }
      &:first-child {
        color: #FF4949;
        &:hover {
          color: #FF7773;
        }
      }
    }
    i {
      margin: 0 18px;
      color: #E9EEF2;
      font-style: normal;
      font-size: 9px;
    }
  }
}
.xtableBtns {
  color: #306DF6;
  height: 32px;
  line-height: 1.5715;
  border-radius: 4px;
  padding: 4px 15px;
  cursor: pointer;
  display: inline-block;
  &:hover {
    background: rgba(0, 0, 0, 0.018);
    /*color: #6896FF;*/
  }
}
/*全局*/
:global {
  .ant-table-tbody > tr.ant-table-row-selected > td,
  .ant-table-tbody > tr.ant-table-row-selected > td:hover,
  .ant-table-tbody > tr.ant-table-row-selected > td:active,
  .ant-table-tbody > tr.ant-table-row-selected:hover > td{
    background: #fff;
  }
  .ant-pagination-options-quick-jumper input {
    text-align: center;
  }
  .ant-table-tbody .ant-table-row:nth-child(2n + 1) .ant-table-cell-fix-left, .ant-table-tbody .ant-table-row:nth-child(2n + 1) .ant-table-cell-fix-right {
    background: #fff;
  }
  .ant-btn-sm {
    height: auto;
  }
  .ant-btn {
    border-radius: 3px;
    padding: 9px 15px;
    line-height: 12px;
    font-size: 12px;
  }
  .ant-table-column-title {}
  .ant-tooltip-arrow-content {
    --antd-arrow-background-color: #ffffff !important;
    background-color: #fff;
  }
  .ant-tooltip-inner {
    background: #ffffff;
    color: #45474d;
    padding: 12px;
  }
  /*弹窗背景颜色*/
  .ant-modal-header {
    background: #F4F6FA;
  }
  /*thead 高度控制*/
  .ant-table {
    line-height: 12px;
  }
  /*table 表头颜色*/
  .ant-table-thead {
    height: 48px;
    background: #F2F3F6 !important;
  }
  /*表格排序移上去背景颜色*/
  .ant-table-thead th.ant-table-column-has-sorters:hover {
    background: #F2F3F6 !important;
  }
  /*表格排序 提示文字*/
  .ant-tooltip-placement-top {
    display: none !important;
  }
  /*table 斑马线*/
  .ant-table-tbody .ant-table-row:nth-child(2n + 1) {
    background-color: #fff;
  }
  .ant-table-thead > tr > th, .ant-table-tbody > tr > td  {
    padding: 13px 16px;
  }
  .ant-table-column-sorters {
    padding: 13px 16px;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曲线人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值