• Cascader 级联选择
    • 何时使用
    • 代码演示
      • 基本
      • 选择即改变
      • 自定义已选项
      • 可以自定义显示
      • 默认值
      • 禁用选项
      • 移入展开
      • 动态加载选项
      • 搜索
      • 大小
      • 自定义字段名
      • 后缀图标
  • API
    • 事件
  • 方法

    Cascader 级联选择

    级联选择框。

    何时使用

    • 需要从一组相关联的数据集合进行选择,例如省市区,公司层级,事物分类等。
    • 从一个较大的数据集合中进行选择时,用多级分类进行分隔,方便选择。
    • 比起 Select 组件,可以在同一个浮层中完成选择,有较好的体验。

    代码演示

    Cascader 级联选择 - 图1

    基本

    省市区级联。

    1. <template>
    2. <a-cascader :options="options" @change="onChange" placeholder="Please select" />
    3. </template>
    4. <script>
    5. export default {
    6. data() {
    7. return {
    8. options: [
    9. {
    10. value: 'zhejiang',
    11. label: 'Zhejiang',
    12. children: [
    13. {
    14. value: 'hangzhou',
    15. label: 'Hangzhou',
    16. children: [
    17. {
    18. value: 'xihu',
    19. label: 'West Lake',
    20. },
    21. ],
    22. },
    23. ],
    24. },
    25. {
    26. value: 'jiangsu',
    27. label: 'Jiangsu',
    28. children: [
    29. {
    30. value: 'nanjing',
    31. label: 'Nanjing',
    32. children: [
    33. {
    34. value: 'zhonghuamen',
    35. label: 'Zhong Hua Men',
    36. },
    37. ],
    38. },
    39. ],
    40. },
    41. ],
    42. };
    43. },
    44. methods: {
    45. onChange(value) {
    46. console.log(value);
    47. },
    48. },
    49. };
    50. </script>

    Cascader 级联选择 - 图2

    选择即改变

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

    1. <template>
    2. <a-cascader :options="options" @change="onChange" changeOnSelect />
    3. </template>
    4. <script>
    5. export default {
    6. data() {
    7. return {
    8. options: [
    9. {
    10. value: 'zhejiang',
    11. label: 'Zhejiang',
    12. children: [
    13. {
    14. value: 'hangzhou',
    15. label: 'Hangzhou',
    16. children: [
    17. {
    18. value: 'xihu',
    19. label: 'West Lake',
    20. },
    21. ],
    22. },
    23. ],
    24. },
    25. {
    26. value: 'jiangsu',
    27. label: 'Jiangsu',
    28. children: [
    29. {
    30. value: 'nanjing',
    31. label: 'Nanjing',
    32. children: [
    33. {
    34. value: 'zhonghuamen',
    35. label: 'Zhong Hua Men',
    36. },
    37. ],
    38. },
    39. ],
    40. },
    41. ],
    42. };
    43. },
    44. methods: {
    45. onChange(value) {
    46. console.log(value);
    47. },
    48. },
    49. };
    50. </script>

    Cascader 级联选择 - 图3

    自定义已选项

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

    1. <template>
    2. <a-cascader
    3. :options="options"
    4. :defaultValue="['zhejiang', 'hangzhou', 'xihu']"
    5. style="width: 100%"
    6. >
    7. <template slot="displayRender" slot-scope="{labels, selectedOptions}">
    8. <span v-for="(label, index) in labels" :key="selectedOptions[index].value">
    9. <span v-if="index === labels.length - 1">
    10. {{label}} (<a @click="e => handleAreaClick(e, label, selectedOptions[index])"
    11. >{{selectedOptions[index].code}}</a
    12. >)
    13. </span>
    14. <span v-else @click="onChange">
    15. {{label}} /
    16. </span>
    17. </span>
    18. </template>
    19. </a-cascader>
    20. </template>
    21. <script>
    22. export default {
    23. data() {
    24. return {
    25. options: [
    26. {
    27. value: 'zhejiang',
    28. label: 'Zhejiang',
    29. children: [
    30. {
    31. value: 'hangzhou',
    32. label: 'Hangzhou',
    33. children: [
    34. {
    35. value: 'xihu',
    36. label: 'West Lake',
    37. code: 752100,
    38. },
    39. ],
    40. },
    41. ],
    42. },
    43. {
    44. value: 'jiangsu',
    45. label: 'Jiangsu',
    46. children: [
    47. {
    48. value: 'nanjing',
    49. label: 'Nanjing',
    50. children: [
    51. {
    52. value: 'zhonghuamen',
    53. label: 'Zhong Hua Men',
    54. code: 453400,
    55. },
    56. ],
    57. },
    58. ],
    59. },
    60. ],
    61. };
    62. },
    63. methods: {
    64. onChange(value) {
    65. console.log(value);
    66. },
    67. handleAreaClick(e, label, option) {
    68. e.stopPropagation();
    69. console.log('clicked', label, option);
    70. },
    71. },
    72. };
    73. </script>

    Cascader 级联选择 - 图4

    可以自定义显示

    切换按钮和结果分开。

    1. <template>
    2. <span>
    3. {{text}} &nbsp;
    4. <a-cascader :options="options" @change="onChange">
    5. <a href="#">Change city</a>
    6. </a-cascader>
    7. </span>
    8. </template>
    9. <script>
    10. export default {
    11. data() {
    12. return {
    13. text: 'Unselect',
    14. options: [
    15. {
    16. value: 'zhejiang',
    17. label: 'Zhejiang',
    18. children: [
    19. {
    20. value: 'hangzhou',
    21. label: 'Hangzhou',
    22. children: [
    23. {
    24. value: 'xihu',
    25. label: 'West Lake',
    26. },
    27. ],
    28. },
    29. ],
    30. },
    31. {
    32. value: 'jiangsu',
    33. label: 'Jiangsu',
    34. children: [
    35. {
    36. value: 'nanjing',
    37. label: 'Nanjing',
    38. children: [
    39. {
    40. value: 'zhonghuamen',
    41. label: 'Zhong Hua Men',
    42. },
    43. ],
    44. },
    45. ],
    46. },
    47. ],
    48. };
    49. },
    50. methods: {
    51. onChange(value, selectedOptions) {
    52. this.text = selectedOptions.map(o => o.label).join(', ');
    53. },
    54. },
    55. };
    56. </script>

    Cascader 级联选择 - 图5

    默认值

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

    1. <template>
    2. <a-cascader
    3. :options="options"
    4. @change="onChange"
    5. :defaultValue="['zhejiang', 'hangzhou', 'xihu']"
    6. />
    7. </template>
    8. <script>
    9. export default {
    10. data() {
    11. return {
    12. options: [
    13. {
    14. value: 'zhejiang',
    15. label: 'Zhejiang',
    16. children: [
    17. {
    18. value: 'hangzhou',
    19. label: 'Hangzhou',
    20. children: [
    21. {
    22. value: 'xihu',
    23. label: 'West Lake',
    24. },
    25. ],
    26. },
    27. ],
    28. },
    29. {
    30. value: 'jiangsu',
    31. label: 'Jiangsu',
    32. children: [
    33. {
    34. value: 'nanjing',
    35. label: 'Nanjing',
    36. children: [
    37. {
    38. value: 'zhonghuamen',
    39. label: 'Zhong Hua Men',
    40. },
    41. ],
    42. },
    43. ],
    44. },
    45. ],
    46. };
    47. },
    48. methods: {
    49. onChange(value) {
    50. console.log(value);
    51. },
    52. },
    53. };
    54. </script>

    Cascader 级联选择 - 图6

    禁用选项

    通过指定 options 里的 disabled 字段。

    1. <template>
    2. <a-cascader :options="options" @change="onChange" />
    3. </template>
    4. <script>
    5. export default {
    6. data() {
    7. return {
    8. options: [
    9. {
    10. value: 'zhejiang',
    11. label: 'Zhejiang',
    12. children: [
    13. {
    14. value: 'hangzhou',
    15. label: 'Hangzhou',
    16. children: [
    17. {
    18. value: 'xihu',
    19. label: 'West Lake',
    20. },
    21. ],
    22. },
    23. ],
    24. },
    25. {
    26. value: 'jiangsu',
    27. label: 'Jiangsu',
    28. disabled: true,
    29. children: [
    30. {
    31. value: 'nanjing',
    32. label: 'Nanjing',
    33. children: [
    34. {
    35. value: 'zhonghuamen',
    36. label: 'Zhong Hua Men',
    37. },
    38. ],
    39. },
    40. ],
    41. },
    42. ],
    43. };
    44. },
    45. methods: {
    46. onChange(value) {
    47. console.log(value);
    48. },
    49. },
    50. };
    51. </script>

    Cascader 级联选择 - 图7

    移入展开

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

    1. <template>
    2. <a-cascader
    3. :options="options"
    4. :displayRender="displayRender"
    5. expandTrigger="hover"
    6. @change="onChange"
    7. placeholder="Please select"
    8. />
    9. </template>
    10. <script>
    11. export default {
    12. data() {
    13. return {
    14. options: [
    15. {
    16. value: 'zhejiang',
    17. label: 'Zhejiang',
    18. children: [
    19. {
    20. value: 'hangzhou',
    21. label: 'Hangzhou',
    22. children: [
    23. {
    24. value: 'xihu',
    25. label: 'West Lake',
    26. },
    27. ],
    28. },
    29. ],
    30. },
    31. {
    32. value: 'jiangsu',
    33. label: 'Jiangsu',
    34. children: [
    35. {
    36. value: 'nanjing',
    37. label: 'Nanjing',
    38. children: [
    39. {
    40. value: 'zhonghuamen',
    41. label: 'Zhong Hua Men',
    42. },
    43. ],
    44. },
    45. ],
    46. },
    47. ],
    48. };
    49. },
    50. methods: {
    51. onChange(value) {
    52. console.log(value);
    53. },
    54. displayRender({ labels }) {
    55. return labels[labels.length - 1];
    56. },
    57. },
    58. };
    59. </script>

    Cascader 级联选择 - 图8

    动态加载选项

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

    注意:loadDatashowSearch 无法一起使用。

    1. <template>
    2. <a-cascader
    3. :options="options"
    4. @change="onChange"
    5. :loadData="loadData"
    6. placeholder="Please select"
    7. changeOnSelect
    8. />
    9. </template>
    10. <script>
    11. export default {
    12. data() {
    13. return {
    14. options: [
    15. {
    16. value: 'zhejiang',
    17. label: 'Zhejiang',
    18. isLeaf: false,
    19. },
    20. {
    21. value: 'jiangsu',
    22. label: 'Jiangsu',
    23. isLeaf: false,
    24. },
    25. ],
    26. };
    27. },
    28. methods: {
    29. onChange(value) {
    30. console.log(value);
    31. },
    32. loadData(selectedOptions) {
    33. const targetOption = selectedOptions[selectedOptions.length - 1];
    34. targetOption.loading = true;
    35. // load options lazily
    36. setTimeout(() => {
    37. targetOption.loading = false;
    38. targetOption.children = [
    39. {
    40. label: `${targetOption.label} Dynamic 1`,
    41. value: 'dynamic1',
    42. },
    43. {
    44. label: `${targetOption.label} Dynamic 2`,
    45. value: 'dynamic2',
    46. },
    47. ];
    48. this.options = [...this.options];
    49. }, 1000);
    50. },
    51. },
    52. };
    53. </script>

    Cascader 级联选择 - 图9

    搜索

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

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

    1. <template>
    2. <a-cascader
    3. :options="options"
    4. :showSearch="{filter}"
    5. @change="onChange"
    6. placeholder="Please select"
    7. />
    8. </template>
    9. <script>
    10. export default {
    11. data() {
    12. return {
    13. options: [
    14. {
    15. value: 'zhejiang',
    16. label: 'Zhejiang',
    17. children: [
    18. {
    19. value: 'hangzhou',
    20. label: 'Hangzhou',
    21. children: [
    22. {
    23. value: 'xihu',
    24. label: 'West Lake',
    25. },
    26. {
    27. value: 'xiasha',
    28. label: 'Xia Sha',
    29. disabled: true,
    30. },
    31. ],
    32. },
    33. ],
    34. },
    35. {
    36. value: 'jiangsu',
    37. label: 'Jiangsu',
    38. children: [
    39. {
    40. value: 'nanjing',
    41. label: 'Nanjing',
    42. children: [
    43. {
    44. value: 'zhonghuamen',
    45. label: 'Zhong Hua men',
    46. },
    47. ],
    48. },
    49. ],
    50. },
    51. ],
    52. };
    53. },
    54. methods: {
    55. onChange(value, selectedOptions) {
    56. console.log(value, selectedOptions);
    57. },
    58. filter(inputValue, path) {
    59. return path.some(
    60. option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1,
    61. );
    62. },
    63. },
    64. };
    65. </script>

    Cascader 级联选择 - 图10

    大小

    不同大小的级联选择器。

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

    Cascader 级联选择 - 图11

    自定义字段名

    自定义字段名。

    1. <template>
    2. <a-cascader
    3. :fieldNames="{ label: 'name', value: 'code', children: 'items' }"
    4. :options="options"
    5. @change="onChange"
    6. placeholder="Please select"
    7. />
    8. </template>
    9. <script>
    10. const options = [
    11. {
    12. code: 'zhejiang',
    13. name: 'Zhejiang',
    14. items: [
    15. {
    16. code: 'hangzhou',
    17. name: 'Hangzhou',
    18. items: [
    19. {
    20. code: 'xihu',
    21. name: 'West Lake',
    22. },
    23. ],
    24. },
    25. ],
    26. },
    27. {
    28. code: 'jiangsu',
    29. name: 'Jiangsu',
    30. items: [
    31. {
    32. code: 'nanjing',
    33. name: 'Nanjing',
    34. items: [
    35. {
    36. code: 'zhonghuamen',
    37. name: 'Zhong Hua Men',
    38. },
    39. ],
    40. },
    41. ],
    42. },
    43. ];
    44. export default {
    45. data() {
    46. return {
    47. options,
    48. };
    49. },
    50. methods: {
    51. onChange(value) {
    52. console.log(value);
    53. },
    54. },
    55. };
    56. </script>

    Cascader 级联选择 - 图12

    后缀图标

    省市区级联。

    1. <template>
    2. <div>
    3. <a-cascader
    4. style="margin-top: 1rem"
    5. :options="options"
    6. @change="onChange"
    7. placeholder="Please select"
    8. >
    9. <a-icon type="smile" slot="suffixIcon" class="test" />
    10. </a-cascader>
    11. <a-cascader
    12. suffixIcon="ab"
    13. style="margin-top: 1rem"
    14. :options="options"
    15. @change="onChange"
    16. placeholder="Please select"
    17. />
    18. </div>
    19. </template>
    20. <script>
    21. export default {
    22. data() {
    23. return {
    24. options: [
    25. {
    26. value: 'zhejiang',
    27. label: 'Zhejiang',
    28. children: [
    29. {
    30. value: 'hangzhou',
    31. label: 'Hangzhou',
    32. children: [
    33. {
    34. value: 'xihu',
    35. label: 'West Lake',
    36. },
    37. ],
    38. },
    39. ],
    40. },
    41. {
    42. value: 'jiangsu',
    43. label: 'Jiangsu',
    44. children: [
    45. {
    46. value: 'nanjing',
    47. label: 'Nanjing',
    48. children: [
    49. {
    50. value: 'zhonghuamen',
    51. label: 'Zhong Hua Men',
    52. },
    53. ],
    54. },
    55. ],
    56. },
    57. ],
    58. };
    59. },
    60. methods: {
    61. onChange(value) {
    62. console.log(value);
    63. },
    64. },
    65. };
    66. </script>

    API

    1. <a-cascader :options="options" @change="onChange" />
    参数说明类型默认值
    allowClear是否支持清除booleantrue
    autoFocus自动获取焦点booleanfalse
    changeOnSelect当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示booleanfalse
    defaultValue默认的选中项string[] | number[][]
    disabled禁用booleanfalse
    displayRender选择后展示的渲染函数,可使用 slot="displayRender" 和 slot-scope="{labels, selectedOptions}"({labels, selectedOptions}) => vNodelabels => labels.join(' / ')
    expandTrigger次级菜单的展开方式,可选 'click' 和 'hover'string'click'
    fieldNames自定义 options 中 label name children 的字段object{ 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-
    popupStyle自定义浮层样式object{}
    popupPlacement浮层预设位置:bottomLeft bottomRight topLeft topRightEnumbottomLeft
    popupVisible控制浮层显隐boolean-
    showSearch在选择框中显示搜索框booleanfalse
    size输入框大小,可选 large default smallstringdefault
    suffixIcon自定义的选择框后缀图标string | VNode | slot-
    value(v-model)指定选中项string[] | number[]-

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

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

    事件

    事件名称说明回调参数
    change选择完成后的回调(value, selectedOptions) => void
    popupVisibleChange显示/隐藏浮层的回调(value) => void

    方法

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

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