用途
Syncfusion React ComboBox 是一个面向 React 的下拉输入组件,用于在输入框与选择列表之间建立连接。用户既可以键入文本进行过滤,也可以从下拉列表中直接选择项目,适合需要“可搜索下拉框”的交互场景。
主要能力
- 混合输入:用户可键入内容过滤,也可从下拉列表中选择。
- 智能过滤:默认按文本搜索,支持自定义过滤逻辑以应对复杂场景。
- 灵活数据源:支持字符串、JSON 对象、OData、Web API、DataManager。
- 丰富 UI:支持项目、页眉、页脚、选中值、无结果状态等模板。
- 性能:虚拟滚动可高效处理数千条项目。
- 全球化:内置本地化、RTL 支持、ARIA 属性。
- 无障碍:完整键盘导航与屏幕阅读器支持。
安装
npm install @syncfusion/ej2-react-dropdowns
使用方式
基础用法(函数组件):
import { ComboBoxComponent } from '@syncfusion/ej2-react-dropdowns';
import '@syncfusion/ej2-base/styles/tailwind3.css';
import '@syncfusion/ej2-react-dropdowns/styles/tailwind3.css';
export default function App() {
const sportsList = ['Badminton', 'Cricket', 'Football', 'Golf', 'Tennis'];
return (
<ComboBoxComponent
id="combobox"
dataSource={sportsList}
placeholder="Select a sport"
allowCustom={true}
/>
);
}
绑定 JSON 对象数据:
export default function App() {
const sportsData = [
{ Id: 'game1', Game: 'Badminton', Players: 2 },
{ Id: 'game2', Game: 'Football', Players: 11 },
{ Id: 'game3', Game: 'Cricket', Players: 11 }
];
const fields = { text: 'Game', value: 'Id' };
return (
<ComboBoxComponent
id="combobox"
dataSource={sportsData}
fields={fields}
placeholder="Select a game"
change={(e) => console.log('Selected:', e.value)}
/>
);
}
常见模式
模式 1:过滤搜索(大数据量)
当列表超过 500 条时,使用过滤配合受控输入仅显示匹配项;数据量超过 5,000 条时,结合 enableVirtualization 并注入 VirtualScroll。
import { ComboBoxComponent, Inject, VirtualScroll } from '@syncfusion/ej2-react-dropdowns';
const [filterValue, setFilterValue] = useState('');
<ComboBoxComponent
dataSource={largeDataset}
fields={{ text: 'name', value: 'id' }}
filtering={(e) => filterByName(e, 'name')}
change={(e) => setFilterValue(e.value)}
allowFiltering={true}
enableVirtualization={true}
popupHeight="200px"
>
<Inject services={[VirtualScroll]} />
</ComboBoxComponent>
模式 2:分组类别
通过 groupBy 字段映射按类别组织项目。
const categorizedData = [
{ Category: 'Sports', Item: 'Cricket', value: 1 },
{ Category: 'Sports', Item: 'Football', value: 2 },
{ Category: 'Games', Item: 'Chess', value: 3 },
{ Category: 'Games', Item: 'Carrom', value: 4 }
];
const fields = {
text: 'Item',
value: 'value',
groupBy: 'Category'
};
<ComboBoxComponent dataSource={categorizedData} fields={fields} />
模式 3:远程数据加载
使用 DataManager 与 Web API 适配器按用户搜索获取数据。
import { DataManager, WebApiAdaptor } from '@syncfusion/ej2-data';
const dataManager = new DataManager({
url: 'https://api.example.com/sports',
adaptor: new WebApiAdaptor()
});
<ComboBoxComponent
dataSource={dataManager}
fields={{ text: 'name', value: 'id' }}
allowFiltering={true}
/>
模式 4:自定义模板
使用 itemTemplate 渲染图标或附加信息。
const itemTemplate = (props) => {
return (
<div className="flex items-center gap-2">
<span className={`icon icon-${props.value}`}></span>
<span>{props.name}</span>
<small className="text-gray-500">({props.players} players)</small>
</div>
);
};
<ComboBoxComponent
dataSource={sportsData}
itemTemplate={itemTemplate}
fields={{ text: 'name', value: 'id' }}
/>
关键属性
| 属性 | 类型 | 说明 | 常见用途 |
|---|---|---|---|
| dataSource | Array|DataManager | 要显示的数据项 | 所有用例 |
| fields | FieldSettingsModel | 映射数据字段(text、value、groupBy、iconCss、disabled) | 复杂数据 |
| placeholder | string | 空值时的提示文本 | UX 引导 |
| allowCustom | boolean | 允许用户输入列表中不存在的自定义值。默认:true | 开放式输入 |
| allowFiltering | boolean | 在弹出层启用过滤栏(搜索框)。默认:false | 搜索能力 |
| enableVirtualization | boolean | 为大数据集启用虚拟滚动。需 <Inject services={[VirtualScroll]} />。默认:false |
大数据集(5,000+ 项) |
| sortOrder | SortOrder | 'None' | 'Ascending' | 'Descending'。默认:null | 排序列表 |
| popupHeight | string|number | 下拉高度(如 '300px')。默认:'300px' | 布局控制 |
| popupWidth | string|number | 下拉宽度(如 '100%')。默认:'100%' | 布局控制 |
| enabled | boolean | 启用/禁用组件。默认:true | 条件渲染 |
| readonly | boolean | 阻止用户输入。默认:false | 只读模式 |
| showClearButton | boolean | 显示清除(×)按钮。默认:true | 允许清除选择 |
| change | EmitType<ChangeEventArgs> | 选择变化时触发 | 事件处理 |
| filtering | EmitType<FilteringEventArgs> | 用户输入时触发;用于自定义过滤逻辑 | 高级搜索 |
| itemTemplate | Function|string | 每个列表项的自定义 HTML | 丰富 UI |
适用场景
- 需要可搜索下拉框的表单输入。
- 数据量较大、需要虚拟滚动或远程加载的选择场景。
- 需要分组、排序、图标或富内容展示的列表。
- 需要本地化、RTL 或无障碍支持的应用。
- 级联/依赖下拉(如国家 → 州 → 城市)、自动填充等常见实现场景。
限制
资料未提供关于收费、价格、平台兼容性、性能上限或效果保证的具体说明,暂未提供。