• 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. value: 'zhejiang',
    10. label: 'Zhejiang',
    11. children: [{
    12. value: 'hangzhou',
    13. label: 'Hangzhou',
    14. children: [{
    15. value: 'xihu',
    16. label: 'West Lake',
    17. }],
    18. }],
    19. }, {
    20. value: 'jiangsu',
    21. label: 'Jiangsu',
    22. children: [{
    23. value: 'nanjing',
    24. label: 'Nanjing',
    25. children: [{
    26. value: 'zhonghuamen',
    27. label: 'Zhong Hua Men',
    28. }],
    29. }],
    30. }]
    31. }
    32. },
    33. methods: {
    34. onChange(value) {
    35. console.log(value);
    36. }
    37. }
    38. }
    39. </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. value: 'zhejiang',
    10. label: 'Zhejiang',
    11. children: [{
    12. value: 'hangzhou',
    13. label: 'Hangzhou',
    14. children: [{
    15. value: 'xihu',
    16. label: 'West Lake',
    17. }],
    18. }],
    19. }, {
    20. value: 'jiangsu',
    21. label: 'Jiangsu',
    22. children: [{
    23. value: 'nanjing',
    24. label: 'Nanjing',
    25. children: [{
    26. value: 'zhonghuamen',
    27. label: 'Zhong Hua Men',
    28. }],
    29. }],
    30. }]
    31. }
    32. },
    33. methods: {
    34. onChange(value) {
    35. console.log(value);
    36. }
    37. }
    38. }
    39. </script>

    Cascader级联选择 - 图3

    自定义已选项

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

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

    Cascader级联选择 - 图4

    可以自定义显示

    切换按钮和结果分开。

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

    Cascader级联选择 - 图5

    默认值

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

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

    Cascader级联选择 - 图7

    移入展开

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

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

    Cascader级联选择 - 图8

    动态加载选项

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

    注意:loadDatashowSearch 无法一起使用。

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

    Cascader级联选择 - 图9

    搜索

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

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

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

    Cascader级联选择 - 图11

    自定义字段名

    自定义字段名。

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

    Cascader级联选择 - 图12

    后缀图标

    省市区级联。

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