antd中的表格穿梭框(Transfer)如何使用

穿梭框是什么?怎么使用?

需求如下:

有一组端口需要分配给具体接口

功能要求:
  1. 需要展示当前端口名称及其所属的接口

  2. 需支持搜索功能可对端口名或接口名进行筛选便于分配

  3. 分配端口时,需检测当前接口内的端口是否满足此接口最低要求

  4. 提供Select下拉框,可供查看及操作具体接口内的端口

  5. 保存操作时,需对各接口数据进行最低要求效验

  6. 操作不满足条件时,需中断数据操作,并展示操作项异常状态

原理:左侧为数据集合,右侧为设置的数据的key值集合
效果图如下:
穿梭框简单用法(基础属性介绍):
javascript 复制代码
<Transfer
            dataSource={staffKeyArr}
            titles={['任务总人员', 'A任务人员']} //标题集合
            targetKeys={AStaffKeyArr} // 显示在右侧的key集合
            // selectedKeys={selectedKeys} // 默认被选中的集合
            //
            onChange={onChange} // 具体数据操作
            onSelectChange={onSelectChange} // 选中项发生改变
            //
            showSearch // 是否展示搜索功能
            // onSearch={handleSearch}
            filterOption={seachFn} // 具体搜索操作
            //
            operations={['to right', 'to left']} // 穿梭框中间图标描述
            // 同时设置两侧的样式
            listStyle={{
                width: 300,
                height: 300,
            }}
            // 单独设置两侧的样式
            // listStyle={(direction) => {
            //     if (direction === 'left') {
            //         return {
            //             width: 300,
            //             backgroundColor: '#f5f5f5',
            //             border: '1px solid #1890ff',
            //         }
            //     } else {
            //         return {
            //             width: 350,
            //             backgroundColor: '#fffbe6',
            //             border: '1px dashed #ffa940',
            //         }
            //     }
            // }}
            //
            // pagination // 是否使用分页
            pagination={{
                pageSize: 5,
                showSizeChanger: true, //是否显示分页器
            }}
            //
            render={(item) => {
                // 一般穿梭框渲染项
                return item.name
            }}
        />

上述代码中的函数介绍,更多函数可查看官网,地址如下:穿梭框 Transfer - Ant Design

常用函数介绍:

tips:掌握onChange+filterOption能解决大部分操作

javascript 复制代码
    // 点击穿梭框中间的图标时的实际操作
    const onChange = (nextTargetKeys, direction, moveKeys) => {
        // nextTargetKeys  移动后的key值集合
        // direction       当前动作
        // moveKeys        当前选中的key值
        setbrWanKeyArr(nextTargetKeys)
    }
    // 搜索实际数据处理函数
    const seachFn = (value, item, direction) => {
        // value  当前搜索的值
        // item  此处可以把次函数理解为filter,item为当前操作的穿梭框内的每一项
        // direction    当前操作的穿梭框位置
        return (
            // 此处对name属性进行筛选(可对多数据进行筛选)
            item.name.indexOf(value) !== -1
        )
    }

    // 对穿梭框的内容选中时触发
    const onSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
        // sourceSelectedKeys 当前选中的key值
        // targetSelectedKeys 当前的具体数值
        console.log(sourceSelectedKeys, targetSelectedKeys, 123)
    }
    // 搜索时触发
    const handleSearch = (direction, value) => {
        // direction    当前操作的穿梭框位置
        // value  当前搜索的值
        console.log('search:', direction, value)
    }
 
穿梭框高阶用法表格穿梭框:

使用场景: 简单穿梭框只能渲染数据中的一项,使用表格穿梭框可随意渲染数据中的任意项

在基础穿梭框的用法上,加以封装调整,代码如下:

表格穿梭框封装处理后使用
javascript 复制代码
const Default = (props) => {
    // 表格渲染
    const columns = [
        {
            dataIndex: 'key',
            title: '端口名称',
        },
        {
            dataIndex: 'alias',
            title: '所属接口',
            render: (tag) => (
                <Tag className="TagCol1">{tag}</Tag>
            ),
        },
    ]

    // 总端口
    const [totalInter, setTotalInter] = useState()
    // 当前分配的接口
    const [nowInter, setNowInter] = useState()
    // 当前分配的接口数据
    const [nowKeys, setNowKeys] = useState([])
    // 需要禁用的端口列表
    const [disableList, setDisableList] = useState([])
    // 异常状态动态类名控制
    const [errorStatus, setErrorStatus] = useState()
    useEffect(() => {
        // 此处对初始各数据进行处理/赋值
    }, [])

    // 数据发生变动时触发
    const onChange = (nextTargetKeys, direction, moveKeys) => {
        // 对当前的操作进行条件1效验,并赋予异常状态
        if (flagXXX) {
            setErrorStatus('TransferRight')
            return
        } else {
            setErrorStatus('')
        }

        // 需要实时数据更新,即需对总数据进行实时更改
        setTotalInter((prev) => {
            prevxxx
        })
        // 更新当前右侧分配的接口数据的key值集合
        setNowKeys(nextTargetKeys)
    }

    // 右侧数据进行切换时触发
    const changeRightData = (val, error) => {
        // 存储当前所操作的接口标识
        setNowInter(val)
        // 更新当前右侧分配的接口数据的key值集合
        setNowKeys(XXXXchangeData)
        // 对当前的操作进行条件2效验,并赋予异常状态
        if (flagXXX) {
            setErrorStatus('TransferRight')
        } else {
            setErrorStatus('')
        }
    }

    // 搜索时触发
    const seachFn = (val, item, direction) => {
        // 当前支持搜索端口名称及所属接口
        return item.key.indexOf(val) !== -1 || item.alias.indexOf(val) !== -1
    }

    // 保存操作时触发
    const saveData = () => {
        // 对当前的操作进行条件3效验,并赋予异常状态
        let vad = false
        let athArr = totalInter.filter((item) => {
            if (XXX) return XXX
        })
        athArr.forEach((item) => {
            if (flagXXX) {
                vad = true
                setErrorStatus('TransferLeft')
                return
            }
        })
        if (vad) return

        // 对当前的操作进行条件4效验,并赋予异常状态
        let arrEmpty = false
        lastArr.forEach((item) => {
            if (flagXXX) {
                arrEmpty = true
                return
            }
        })
        if (arrEmpty) return

        // 所有效验通过后触发函数
        props.save(lastArr)
    }

    return (
        <>
            <TableTransfer
                dataSource={totalInter} // 数据源
                targetKeys={nowKeys} // 当前右侧操作的接口数据key值集合
                showSelectAll={false}
                onChange={onChange}
                showSearch
                filterOption={seachFn}
                Columns={columns} // 表格渲染规则
                operations={['分配', '重置']}
                // 以下为自定义传递
                changeRightData={changeRightData} // 右侧插入的下拉框切换数据函数
                selectList={selectList} // 动态下拉框列表
                disabledList={disableList} // 动态禁用项
                transferStatus={errorStatus} // 动态类名,控制左侧或右侧异常
                nowInter={nowInter} // 动态控制当前操作的接口
            />

            <Button type="primary" onClick={saveData}>
                {L.Save}
            </Button>
        </>
    )
}
export default Default
表格穿梭框封装处理
javascript 复制代码
// 对穿梭框进行封装
const TableTransfer = ({ Columns, transferStatus, ...restProps }) => {
    return (
        // className={transferStatus} 控制异常状态
        <Transfer className={transferStatus} {...restProps}>
            {({
                direction,
                filteredItems,
                onItemSelect,
                onItemSelectAll,
                selectedKeys: selectedList,
            }) => {
                const columns = Columns
                // antd的表格功能配置项,具体可查看官网
                const rowSelection = {
                    // 选择框的默认属性配置 (禁用)
                    getCheckboxProps: (item) => {
                        return {
                            disabled:
                                restProps.disabledList.indexOf(item.key) !== -1,
                        }
                    },
                    // 全选操作处理
                    onChange: (nowKeys, keysData) => {
                        onItemSelectAll(nowKeys, 'replace')
                    },
                    selectedRowKeys: selectedList,
                    selections: [
                        Table.SELECTION_ALL,
                        Table.SELECTION_INVERT,
                        Table.SELECTION_NONE,
                    ],
                }

                return (
                    <>
                        {/* 插入的Select下拉框 */}
                        {/* direction === 'right' 只插入右侧
                            restProps.selectList[0]  下拉框初始值渲染处理
                         */}
                        {direction === 'right' && restProps.selectList[0] && (
                            <div>
                                <Select
                                    onChange={(val) => {
                                        restProps.changeRightData(val)
                                    }} // 切换数据处理函数
                                    value={restProps.nowInter}
                                    options={restProps.selectList}
                                />
                            </div>
                        )}
                        <Table
                            rowSelection={rowSelection}
                            columns={columns}
                            dataSource={filteredItems}
                            size="small"
                            // 可对表格行数据进行操作处理
                            onRow={({ key }) => ({
                                onClick: () => {
                                    onItemSelect(
                                        key,
                                        !listSelectedKeys.includes(key)
                                    )
                                },
                            })}
                        />
                    </>
                )
            }}
        </Transfer>
    )
}
相关推荐
Cache技术分享几秒前
63. Java 类和对象 - static 关键字
前端·后端
汤面不加鱼丸7 分钟前
flutter实践:比例对比线图实现
前端·flutter
Jenlybein10 分钟前
进阶学习 Javascript ? 来看看这篇系统复习笔记 [ 面向对象篇 ]
前端·javascript·面试
专业掘金12 分钟前
0429 手打基础丸
前端
还有发量的前端程序员13 分钟前
Vue3初始化完整过程和原理
前端
Jenlybein13 分钟前
进阶学习 Javascript ? 来看看这篇系统复习笔记 [ Generator 篇 ]
前端·javascript·面试
绅士玖16 分钟前
Vue.js 小知识点大揭秘:提升开发效率的实用技巧
前端·vue.js
彭不懂赶紧问16 分钟前
鸿蒙NEXT开发浅进阶到精通04:类似支付宝横向导航栏与list组件联动随航
前端·harmonyos
Jenlybein16 分钟前
进阶学习 Javascript ? 来看看这篇系统复习笔记 [ Promise 与 async 篇 ]
前端·javascript·面试
全栈老李18 分钟前
【高频考点精讲】JavaScript中的访问者模式:从AST解析到数据转换的艺术
javascript