antd中的表格穿梭框(Transfer)如何使用
穿梭框是什么?怎么使用?
需求如下:
有一组端口需要分配给具体接口
功能要求:
1. 需要展示当前端口名称及其所属的接口
2. 需支持搜索功能可对端口名或接口名进行筛选便于分配
3. 分配端口时,需检测当前接口内的端口是否满足此接口最低要求
4. 提供Select下拉框,可供查看及操作具体接口内的端口
5. 保存操作时,需对各接口数据进行最低要求效验
6. 操作不满足条件时,需中断数据操作,并展示操作项异常状态
原理:左侧为数据集合,右侧为设置的数据的key值集合
效果图如下:
穿梭框简单用法(基础属性介绍):
<TransferdataSource={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能解决大部分操作
// 点击穿梭框中间的图标时的实际操作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)}
穿梭框高阶用法表格穿梭框:
使用场景: 简单穿梭框只能渲染数据中的一项,使用表格穿梭框可随意渲染数据中的任意项
在基础穿梭框的用法上,加以封装调整,代码如下:
表格穿梭框封装处理后使用
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 = falselet athArr = totalInter.filter((item) => {if (XXX) return XXX})athArr.forEach((item) => {if (flagXXX) {vad = truesetErrorStatus('TransferLeft')return}})if (vad) return// 对当前的操作进行条件4效验,并赋予异常状态let arrEmpty = falselastArr.forEach((item) => {if (flagXXX) {arrEmpty = truereturn}})if (arrEmpty) return// 所有效验通过后触发函数props.save(lastArr)}return (<><TableTransferdataSource={totalInter} // 数据源targetKeys={nowKeys} // 当前右侧操作的接口数据key值集合showSelectAll={false}onChange={onChange}showSearchfilterOption={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
表格穿梭框封装处理
// 对穿梭框进行封装
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><SelectonChange={(val) => {restProps.changeRightData(val)}} // 切换数据处理函数value={restProps.nowInter}options={restProps.selectList}/></div>)}<TablerowSelection={rowSelection}columns={columns}dataSource={filteredItems}size="small"// 可对表格行数据进行操作处理onRow={({ key }) => ({onClick: () => {onItemSelect(key,!listSelectedKeys.includes(key))},})}/></>)}}</Transfer>)
}