Transfer穿梭框
需要在多个可选项中进行多选时。
比起 Select 和 TreeSelect,穿梭框占据更大的空间,可以展示可选项的更多信息。
穿梭选择框用直观的方式在两栏中移动元素,完成选择行为。
选择一个或以上的选项后,点击对应的方向键,可以把选中的选项移动到另一栏。其中,左边一栏为 ,右边一栏为 target
,API 的设计也反映了这两个概念。
最基本的用法,展示了 dataSource
、targetKeys
、每行的渲染函数 render
以及回调函数 onChange
onSelectChange
onScroll
的用法。
带搜索框的穿梭框,可以自定义搜索函数。
import { Transfer } from 'antd';
class App extends React.Component {
state = {
mockData: [],
targetKeys: [],
};
componentDidMount() {
this.getMock();
}
getMock = () => {
const targetKeys = [];
const mockData = [];
for (let i = 0; i < 20; i++) {
const data = {
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
chosen: Math.random() * 2 > 1,
};
if (data.chosen) {
targetKeys.push(data.key);
}
mockData.push(data);
}
this.setState({ mockData, targetKeys });
};
filterOption = (inputValue, option) => option.description.indexOf(inputValue) > -1;
handleChange = targetKeys => {
this.setState({ targetKeys });
};
handleSearch = (dir, value) => {
console.log('search:', dir, value);
};
render() {
return (
<Transfer
dataSource={this.state.mockData}
showSearch
filterOption={this.filterOption}
targetKeys={this.state.targetKeys}
onChange={this.handleChange}
onSearch={this.handleSearch}
render={item => item.title}
/>
);
}
}
ReactDOM.render(<App />, mountNode);
穿梭框高级用法,可配置操作文案,可定制宽高,可对底部进行自定义渲染。
import { Transfer } from 'antd';
class App extends React.Component {
state = {
mockData: [],
targetKeys: [],
};
componentDidMount() {
this.getMock();
}
getMock = () => {
const targetKeys = [];
for (let i = 0; i < 20; i++) {
const data = {
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
chosen: Math.random() * 2 > 1,
if (data.chosen) {
targetKeys.push(data.key);
}
mockData.push(data);
}
this.setState({ mockData, targetKeys });
};
handleChange = (targetKeys, direction, moveKeys) => {
console.log(targetKeys, direction, moveKeys);
this.setState({ targetKeys });
};
renderItem = item => {
const customLabel = (
<span className="custom-item">
{item.title} - {item.description}
</span>
);
return {
label: customLabel, // for displayed item
value: item.title, // for title and filter matching
};
};
render() {
return (
<Transfer
dataSource={this.state.mockData}
listStyle={{
width: 300,
height: 300,
}}
targetKeys={this.state.targetKeys}
onChange={this.handleChange}
render={this.renderItem}
/>
);
}
}
ReactDOM.render(<App />, mountNode);
使用 Table 组件作为自定义渲染列表。
使用 Tree 组件作为自定义渲染列表。
import { Transfer, Tree } from 'antd';
const { TreeNode } = Tree;
// Customize Table Transfer
const isChecked = (selectedKeys, eventKey) => {
return selectedKeys.indexOf(eventKey) !== -1;
};
const generateTree = (treeNodes = [], checkedKeys = []) => {
return treeNodes.map(({ children, ...props }) => (
<TreeNode {...props} disabled={checkedKeys.includes(props.key)}>
{generateTree(children, checkedKeys)}
</TreeNode>
));
};
const TreeTransfer = ({ dataSource, targetKeys, ...restProps }) => {
const transferDataSource = [];
function flatten(list = []) {
list.forEach(item => {
transferDataSource.push(item);
flatten(item.children);
});
}
flatten(dataSource);
return (
<Transfer
targetKeys={targetKeys}
dataSource={transferDataSource}
className="tree-transfer"
render={item => item.title}
showSelectAll={false}
>
{({ direction, onItemSelect, selectedKeys }) => {
if (direction === 'left') {
const checkedKeys = [...selectedKeys, ...targetKeys];
return (
<Tree
checkable
checkStrictly
defaultExpandAll
checkedKeys={checkedKeys}
onCheck={(
_,
{
node: {
props: { eventKey },
},
},
) => {
onItemSelect(eventKey, !isChecked(checkedKeys, eventKey));
}}
onSelect={(
_,
{
node: {
props: { eventKey },
},
},
) => {
onItemSelect(eventKey, !isChecked(checkedKeys, eventKey));
}}
>
{generateTree(dataSource, targetKeys)}
</Tree>
);
}
}}
</Transfer>
);
};
const treeData = [
{ key: '0-0', title: '0-0' },
{
key: '0-1',
title: '0-1',
children: [{ key: '0-1-0', title: '0-1-0' }, { key: '0-1-1', title: '0-1-1' }],
},
{ key: '0-2', title: '0-3' },
];
class App extends React.Component {
state = {
targetKeys: [],
};
onChange = targetKeys => {
console.log('Target Keys:', targetKeys);
this.setState({ targetKeys });
};
render() {
const { targetKeys } = this.state;
return (
<div>
<TreeTransfer dataSource={treeData} targetKeys={targetKeys} onChange={this.onChange} />
</div>
);
}
}
ReactDOM.render(<App />, mountNode);
Render Props
3.18.0 新增。Transfer 支持接收 children
自定义渲染列表,并返回以下参数:
参数 | 说明 | 类型 | 版本 |
---|---|---|---|
direction | 渲染列表的方向 | 'left' | 'right' | 3.18.0 |
disabled | 是否禁用列表 | boolean | 3.18.0 |
filteredItems | 过滤后的数据 | TransferItem[] | 3.18.0 |
onItemSelect | 勾选条目 | (key: string, selected: boolean) | 3.18.0 |
onItemSelectAll | 勾选一组条目 | (keys: string[], selected: boolean) | 3.18.0 |
selectedKeys | 选中的条目 | string[] | 3.18.0 |
参考示例
如果你的数据没有这个属性,务必使用 rowKey
来指定数据列的主键。
// 比如你的数据主键是 uid