• Cascader级联选择
    • 何时使用
    • 代码演示
    • API
    • 方法

    Cascader级联选择

    级联选择框。

    何时使用

    • 需要从一组相关联的数据集合进行选择,例如省市区,公司层级,事物分类等。

    • 从一个较大的数据集合中进行选择时,用多级分类进行分隔,方便选择。

    • 比起 Select 组件,可以在同一个浮层中完成选择,有较好的体验。

    代码演示

    Cascader 级联选择 - 图1

    基本

    省市区级联。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hangzhou',
    10. children: [
    11. {
    12. value: 'xihu',
    13. label: 'West Lake',
    14. },
    15. ],
    16. },
    17. ],
    18. },
    19. {
    20. value: 'jiangsu',
    21. label: 'Jiangsu',
    22. children: [
    23. {
    24. value: 'nanjing',
    25. label: 'Nanjing',
    26. children: [
    27. {
    28. value: 'zhonghuamen',
    29. label: 'Zhong Hua Men',
    30. },
    31. ],
    32. },
    33. ],
    34. },
    35. ];
    36. function onChange(value) {
    37. console.log(value);
    38. }
    39. ReactDOM.render(
    40. <Cascader options={options} onChange={onChange} placeholder="Please select" />,
    41. mountNode,
    42. );

    Cascader 级联选择 - 图2

    可以自定义显示

    切换按钮和结果分开。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hangzhou',
    10. },
    11. ],
    12. },
    13. {
    14. value: 'jiangsu',
    15. label: 'Jiangsu',
    16. children: [
    17. {
    18. value: 'nanjing',
    19. label: 'Nanjing',
    20. },
    21. ],
    22. },
    23. ];
    24. class CitySwitcher extends React.Component {
    25. state = {
    26. text: 'Unselect',
    27. };
    28. onChange = (value, selectedOptions) => {
    29. this.setState({
    30. text: selectedOptions.map(o => o.label).join(', '),
    31. });
    32. };
    33. render() {
    34. return (
    35. <span>
    36. {this.state.text}
    37. &nbsp;
    38. <Cascader options={options} onChange={this.onChange}>
    39. <a href="#">Change city</a>
    40. </Cascader>
    41. </span>
    42. );
    43. }
    44. }
    45. ReactDOM.render(<CitySwitcher />, mountNode);

    Cascader 级联选择 - 图3

    禁用选项

    通过指定 options 里的 disabled 字段。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hangzhou',
    10. children: [
    11. {
    12. value: 'xihu',
    13. label: 'West Lake',
    14. },
    15. ],
    16. },
    17. ],
    18. },
    19. {
    20. value: 'jiangsu',
    21. label: 'Jiangsu',
    22. disabled: true,
    23. children: [
    24. {
    25. value: 'nanjing',
    26. label: 'Nanjing',
    27. children: [
    28. {
    29. value: 'zhonghuamen',
    30. label: 'Zhong Hua Men',
    31. },
    32. ],
    33. },
    34. ],
    35. },
    36. ];
    37. function onChange(value) {
    38. console.log(value);
    39. }
    40. ReactDOM.render(<Cascader options={options} onChange={onChange} />, mountNode);

    Cascader 级联选择 - 图4

    大小

    不同大小的级联选择器。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hangzhou',
    10. children: [
    11. {
    12. value: 'xihu',
    13. label: 'West Lake',
    14. },
    15. ],
    16. },
    17. ],
    18. },
    19. {
    20. value: 'jiangsu',
    21. label: 'Jiangsu',
    22. children: [
    23. {
    24. value: 'nanjing',
    25. label: 'Nanjing',
    26. children: [
    27. {
    28. value: 'zhonghuamen',
    29. label: 'Zhong Hua Men',
    30. },
    31. ],
    32. },
    33. ],
    34. },
    35. ];
    36. function onChange(value) {
    37. console.log(value);
    38. }
    39. ReactDOM.render(
    40. <div>
    41. <Cascader size="large" options={options} onChange={onChange} />
    42. <br />
    43. <br />
    44. <Cascader options={options} onChange={onChange} />
    45. <br />
    46. <br />
    47. <Cascader size="small" options={options} onChange={onChange} />
    48. <br />
    49. <br />
    50. </div>,
    51. mountNode,
    52. );

    Cascader 级联选择 - 图5

    搜索

    可以直接搜索选项并选择。

    Cascader[showSearch] 暂不支持服务端搜索,更多信息见 #5547

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hangzhou',
    10. children: [
    11. {
    12. value: 'xihu',
    13. label: 'West Lake',
    14. },
    15. {
    16. value: 'xiasha',
    17. label: 'Xia Sha',
    18. disabled: true,
    19. },
    20. ],
    21. },
    22. ],
    23. },
    24. {
    25. value: 'jiangsu',
    26. label: 'Jiangsu',
    27. children: [
    28. {
    29. value: 'nanjing',
    30. label: 'Nanjing',
    31. children: [
    32. {
    33. value: 'zhonghuamen',
    34. label: 'Zhong Hua men',
    35. },
    36. ],
    37. },
    38. ],
    39. },
    40. ];
    41. function onChange(value, selectedOptions) {
    42. console.log(value, selectedOptions);
    43. }
    44. function filter(inputValue, path) {
    45. return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
    46. }
    47. ReactDOM.render(
    48. <Cascader
    49. options={options}
    50. onChange={onChange}
    51. placeholder="Please select"
    52. showSearch={{ filter }}
    53. />,
    54. mountNode,
    55. );

    Cascader 级联选择 - 图6

    自定义字段名

    自定义字段名。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. code: 'zhejiang',
    5. name: 'Zhejiang',
    6. items: [
    7. {
    8. code: 'hangzhou',
    9. name: 'Hangzhou',
    10. items: [
    11. {
    12. code: 'xihu',
    13. name: 'West Lake',
    14. },
    15. ],
    16. },
    17. ],
    18. },
    19. {
    20. code: 'jiangsu',
    21. name: 'Jiangsu',
    22. items: [
    23. {
    24. code: 'nanjing',
    25. name: 'Nanjing',
    26. items: [
    27. {
    28. code: 'zhonghuamen',
    29. name: 'Zhong Hua Men',
    30. },
    31. ],
    32. },
    33. ],
    34. },
    35. ];
    36. function onChange(value) {
    37. console.log(value);
    38. }
    39. ReactDOM.render(
    40. <Cascader
    41. fieldNames={{ label: 'name', value: 'code', children: 'items' }}
    42. options={options}
    43. onChange={onChange}
    44. placeholder="Please select"
    45. />,
    46. mountNode,
    47. );

    Cascader 级联选择 - 图7

    默认值

    默认值通过数组的方式指定。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hangzhou',
    10. children: [
    11. {
    12. value: 'xihu',
    13. label: 'West Lake',
    14. },
    15. ],
    16. },
    17. ],
    18. },
    19. {
    20. value: 'jiangsu',
    21. label: 'Jiangsu',
    22. children: [
    23. {
    24. value: 'nanjing',
    25. label: 'Nanjing',
    26. children: [
    27. {
    28. value: 'zhonghuamen',
    29. label: 'Zhong Hua Men',
    30. },
    31. ],
    32. },
    33. ],
    34. },
    35. ];
    36. function onChange(value) {
    37. console.log(value);
    38. }
    39. ReactDOM.render(
    40. <Cascader
    41. defaultValue={['zhejiang', 'hangzhou', 'xihu']}
    42. options={options}
    43. onChange={onChange}
    44. />,
    45. mountNode,
    46. );

    Cascader 级联选择 - 图8

    移入展开

    通过移入展开下级菜单,点击完成选择。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hangzhou',
    10. children: [
    11. {
    12. value: 'xihu',
    13. label: 'West Lake',
    14. },
    15. ],
    16. },
    17. ],
    18. },
    19. {
    20. value: 'jiangsu',
    21. label: 'Jiangsu',
    22. children: [
    23. {
    24. value: 'nanjing',
    25. label: 'Nanjing',
    26. children: [
    27. {
    28. value: 'zhonghuamen',
    29. label: 'Zhong Hua Men',
    30. },
    31. ],
    32. },
    33. ],
    34. },
    35. ];
    36. function onChange(value) {
    37. console.log(value);
    38. }
    39. // Just show the latest item.
    40. function displayRender(label) {
    41. return label[label.length - 1];
    42. }
    43. ReactDOM.render(
    44. <Cascader
    45. options={options}
    46. expandTrigger="hover"
    47. displayRender={displayRender}
    48. onChange={onChange}
    49. />,
    50. mountNode,
    51. );

    Cascader 级联选择 - 图9

    选择即改变

    这种交互允许只选中父级选项。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hanzhou',
    10. children: [
    11. {
    12. value: 'xihu',
    13. label: 'West Lake',
    14. },
    15. ],
    16. },
    17. ],
    18. },
    19. {
    20. value: 'jiangsu',
    21. label: 'Jiangsu',
    22. children: [
    23. {
    24. value: 'nanjing',
    25. label: 'Nanjing',
    26. children: [
    27. {
    28. value: 'zhonghuamen',
    29. label: 'Zhong Hua Men',
    30. },
    31. ],
    32. },
    33. ],
    34. },
    35. ];
    36. function onChange(value) {
    37. console.log(value);
    38. }
    39. ReactDOM.render(<Cascader options={options} onChange={onChange} changeOnSelect />, mountNode);

    Cascader 级联选择 - 图10

    自定义已选项

    例如给最后一项加上邮编链接。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. children: [
    7. {
    8. value: 'hangzhou',
    9. label: 'Hangzhou',
    10. children: [
    11. {
    12. value: 'xihu',
    13. label: 'West Lake',
    14. code: 752100,
    15. },
    16. ],
    17. },
    18. ],
    19. },
    20. {
    21. value: 'jiangsu',
    22. label: 'Jiangsu',
    23. children: [
    24. {
    25. value: 'nanjing',
    26. label: 'Nanjing',
    27. children: [
    28. {
    29. value: 'zhonghuamen',
    30. label: 'Zhong Hua Men',
    31. code: 453400,
    32. },
    33. ],
    34. },
    35. ],
    36. },
    37. ];
    38. function handleAreaClick(e, label, option) {
    39. e.stopPropagation();
    40. console.log('clicked', label, option);
    41. }
    42. const displayRender = (labels, selectedOptions) =>
    43. labels.map((label, i) => {
    44. const option = selectedOptions[i];
    45. if (i === labels.length - 1) {
    46. return (
    47. <span key={option.value}>
    48. {label} (<a onClick={e => handleAreaClick(e, label, option)}>{option.code}</a>)
    49. </span>
    50. );
    51. }
    52. return <span key={option.value}>{label} / </span>;
    53. });
    54. ReactDOM.render(
    55. <Cascader
    56. options={options}
    57. defaultValue={['zhejiang', 'hangzhou', 'xihu']}
    58. displayRender={displayRender}
    59. style={{ width: '100%' }}
    60. />,
    61. mountNode,
    62. );

    Cascader 级联选择 - 图11

    动态加载选项

    使用 loadData 实现动态加载选项。

    注意:loadDatashowSearch 无法一起使用。

    1. import { Cascader } from 'antd';
    2. const options = [
    3. {
    4. value: 'zhejiang',
    5. label: 'Zhejiang',
    6. isLeaf: false,
    7. },
    8. {
    9. value: 'jiangsu',
    10. label: 'Jiangsu',
    11. isLeaf: false,
    12. },
    13. ];
    14. class LazyOptions extends React.Component {
    15. state = {
    16. options,
    17. };
    18. onChange = (value, selectedOptions) => {
    19. console.log(value, selectedOptions);
    20. };
    21. loadData = selectedOptions => {
    22. const targetOption = selectedOptions[selectedOptions.length - 1];
    23. targetOption.loading = true;
    24. // load options lazily
    25. setTimeout(() => {
    26. targetOption.loading = false;
    27. targetOption.children = [
    28. {
    29. label: `${targetOption.label} Dynamic 1`,
    30. value: 'dynamic1',
    31. },
    32. {
    33. label: `${targetOption.label} Dynamic 2`,
    34. value: 'dynamic2',
    35. },
    36. ];
    37. this.setState({
    38. options: [...this.state.options],
    39. });
    40. }, 1000);
    41. };
    42. render() {
    43. return (
    44. <Cascader
    45. options={this.state.options}
    46. loadData={this.loadData}
    47. onChange={this.onChange}
    48. changeOnSelect
    49. />
    50. );
    51. }
    52. }
    53. ReactDOM.render(<LazyOptions />, mountNode);

    API

    1. <Cascader options="{options}" onChange="{onChange}" />
    参数说明类型默认值
    allowClear是否支持清除booleantrue
    autoFocus自动获取焦点booleanfalse
    changeOnSelect当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示booleanfalse
    className自定义类名string-
    defaultValue默认的选中项string[][]
    disabled禁用booleanfalse
    displayRender选择后展示的渲染函数(label, selectedOptions) => ReactNodelabel => label.join(' / ')
    expandTrigger次级菜单的展开方式,可选 'click' 和 'hover'string'click'
    fieldNames自定义 options 中 label name children 的字段(注意,3.7.0 之前的版本为 filedNamesobject{ label: 'label', value: 'value', children: 'children' }
    getPopupContainer菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。示例Function(triggerNode)() => document.body
    loadData用于动态加载选项,无法与 showSearch 一起使用(selectedOptions) => void-
    notFoundContent当下拉列表为空时显示的内容string'Not Found'
    options可选项数据源object-
    placeholder输入框占位文本string'请选择'
    popupClassName自定义浮层类名string-
    popupPlacement浮层预设位置:bottomLeft bottomRight topLeft topRightEnumbottomLeft
    popupVisible控制浮层显隐boolean-
    showSearch在选择框中显示搜索框booleanfalse
    size输入框大小,可选 large default smallstringdefault
    style自定义样式string-
    suffixIcon自定义的选择框后缀图标ReactNode-
    value指定选中项string[]-
    onChange选择完成后的回调(value, selectedOptions) => void-
    onPopupVisibleChange显示/隐藏浮层的回调(value) => void-

    showSearch 为对象时,其中的字段:

    参数说明类型默认值
    filter接收 inputValue path 两个参数,当 path 符合筛选条件时,应返回 true,反之则返回 false。function(inputValue, path): boolean
    limit搜索结果展示数量number | false50
    matchInputWidth搜索结果列表是否与输入框同宽boolean
    render用于渲染 filter 后的选项function(inputValue, path): ReactNode
    sort用于排序 filter 后的选项function(a, b, inputValue)

    方法

    名称描述
    blur()移除焦点
    focus()获取焦点

    注意,如果需要获得中国省市区数据,可以参考 china-division。