Skip to content

级联选择 Cascader

指在选择器选项数量较多时,采用多级分类的方式将选项进行分隔。

基本使用

级联选择器的基本用法。


代码事例
vue
<template>
  <fk-space direction="vertical" size="large">
    <fk-cascader :options="options" :style="{width:'320px'}" placeholder="Please select ..." />
    <fk-cascader :options="options" default-value="datunli" expand-trigger="hover" :style="{width:'320px'}" placeholder="Please select ..." />
  </fk-space>
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      options
    }
  },
}
</script>

允许清除

允许清除。


代码事例
vue
<template>
  <fk-cascader
v-model="value" :options="options" tag-nowrap :style="{width:'320px'}" placeholder="Please select ..."
              allow-clear />
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const value = ref('datunli');

    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      value,
      options
    }
  },
}
</script>

禁用选项

指定 optiondisabledtrue,可以禁用该选项。


代码事例
vue
<template>
  <fk-cascader :options="options" :style="{width:'320px'}" placeholder="Please select ..." />
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
            disabled: true
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
                disabled: true
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      options
    }
  },
}
</script>

自定义输入框的展示值

利用 formatLabel 对显示的内容进行自定义处理。


代码事例
vue

<template>
  <fk-cascader :options="options" default-value="datunli" :style="{width:'320px'}" placeholder="Please select ..." :format-label="format" />
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];

    const format = (options) => {
      const labels = options.map(option => option.label)
      return labels.join('-')
    }

    return {
      options,
      format
    }
  },
}
</script>

多选模式

通过设置 multiple 开启多选模式。


代码事例
vue
<template>
  <fk-cascader :options="options" tag-nowrap :default-value="['datunli']" :style="{width:'320px'}" placeholder="Please select ..." multiple/>
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
          {
            value: '1xicheng',
            label: '1Xicheng',
            children: [
              {
                value: '1jinrongjie',
                label: '1Jinrongjie',
              },
              {
                value: '1tianqiao',
                label: '1Tianqiao',
              },
            ],
          },{
            value: '2xicheng',
            label: '2Xicheng',
            children: [
              {
                value: '2jinrongjie',
                label: '2Jinrongjie',
              },
              {
                value: '2tianqiao',
                label: '2Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      options
    }
  },
}
</script>

严格选择模式

设置属性 check-strictly,开启严格选择模式,点击任何结点都可以选择。多选时将会解除父子节点的关联。


代码事例
vue
<template>
  <fk-space direction="vertical" size="large">
    <fk-cascader :options="options" default-value="beijing" :style="{width:'320px'}" placeholder="Please select ..." check-strictly />
    <fk-cascader :options="options" tag-nowrap :default-value="['beijing']" :style="{width:'320px'}" placeholder="Please select ..." multiple check-strictly />
  </fk-space>
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
            disabled: true
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      options
    }
  },
}
</script>

加载中

选择框和下拉菜单显示加载中状态。


代码事例
vue
<template>
  <fk-cascader :options="[]" :style="{width:'320px'}" placeholder="Please select ..." loading />
</template>

子选项懒加载

通过 load-more 属性可以开启数据懒加载功能。 开启数据懒加载功能后,需要在叶子节点标注 isLeaf: true,没有标注且没有 children 属性的节点会认为需要懒加载处理。 load-more 属性有提供 done 函数进行回调,可以在回调中传入懒加载的子数据。如果 done 函数没有传入数据会认为懒加载失败,此节点可以再次触发懒加载。


代码事例
vue
<template>
  <fk-space>
    <fk-cascader :options="options" :style="{width:'320px'}" placeholder="Please select ..." :load-more="loadMore"/>
  </fk-space>
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
          },
          {
            value: 'haidian',
            label: 'Haidian',
            isLeaf: true
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
            isLeaf: true
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
            isLeaf: true
          },
        ],
      },
    ];
    const loadMore = (option, done) => {
      window.setTimeout(() => {
        const nodes = [{
          value: `${option.value}-option1`,
          label: `${option.label}-Option1`,
          isLeaf: true
        }, {
          value: `${option.value}-option2`,
          label: `${option.label}-Option2`,
          isLeaf: true
        }]
        done(nodes)
      }, 2000)
    };

    return {
      options,
      loadMore
    }
  },
}
</script>

允许搜索

通过设置 allow-search 让输入框支持搜索功能。


代码事例
vue
<template>
  <fk-cascader :options="options" :style="{width:'320px'}" placeholder="Please select ..." allow-search/>
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      options
    }
  },
}
</script>

路径模式

modelValue 使用路径作为值。


代码事例
vue
<template>
  <fk-space direction="vertical" size="large">
    <fk-cascader
:options="options" :style="{width:'320px'}" placeholder="Please select ..." path-mode
                @change="handleChange" />
    <fk-cascader
:options="options"
                :default-value="[['beijing','chaoyang','datunli']]"
                :style="{width:'320px'}"
                placeholder="Please select ..."
                path-mode
                @change="handleChange" />
  </fk-space>
</template>

<script>
export default {
  setup() {
    const handleChange = (path) => {
      console.log(path)
    }

    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      options,
      handleChange
    }
  },
}
</script>

回退选项

组件默认会展示在选项中不存在的值,可通过 fallback 自定义展示或者关闭


代码事例
vue
<template>
  <fk-space direction="vertical" size="large">
    <fk-cascader v-model="value" :options="options" :style="{width:'320px'}" placeholder="Please select ..." multiple />
    <fk-cascader
v-model="value2" :options="options" :style="{width:'320px'}"
                placeholder="Please select ..." path-mode multiple :fallback="fallback" />
  </fk-space>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const value = ref(['datunli', 'wuhou']);
    const value2 = ref([['beijing', 'chaoyang', 'datunli'], ['sichuan', 'chengdu', 'wuhou']]);
    const fallback = (value) => {
      return value.map(item => item.toUpperCase()).join('-')
    }

    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      options,
      value,
      value2,
      fallback
    }
  },
}
</script>

自定义字段名

可以通过 field-names 属性自定义 options 中数据的格式。


代码事例
vue
<template>
  <fk-cascader
:options="options" :field-names="fieldNames" :style="{width:'320px'}"
            placeholder="Please select ..." />
</template>

<script>
import { reactive } from 'vue';

export default {
  setup() {
    const fieldNames = {value: 'city', label: 'text'}
    const options = reactive([
      {
        city: 'beijing',
        text: 'Beijing',
        children: [
          {
            city: 'chaoyang',
            text: 'ChaoYang',
            children: [
              {
                city: 'datunli',
                text: 'Datunli',
              },
            ],
          },
          {
            city: 'haidian',
            text: 'Haidian',
          },
          {
            city: 'dongcheng',
            text: 'Dongcheng',
          },
          {
            city: 'xicheng',
            text: 'Xicheng',
            children: [
              {
                city: 'jinrongjie',
                text: 'Jinrongjie',
              },
              {
                city: 'tianqiao',
                text: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        city: 'shanghai',
        text: 'Shanghai',
        children: [
          {
            city: 'huangpu',
            text: 'Huangpu',
          },
        ],
      },
    ]);

    return {
      fieldNames,
      options
    }
  }
}
</script>

展开子菜单

通过设置 expand-child 可以在选择时展开第一个子菜单


代码事例
vue
<template>
  <fk-cascader :options="options" :style="{width:'320px'}" placeholder="Please select ..." expand-child/>
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      options
    }
  },
}
</script>

级联菜单

级联菜单可以单独使用,此时为 数据展示 组件


代码事例
vue
<template>
  <fk-cascader-panel v-model="value" :options="options" expand-child/>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const value = ref('');

    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: [
          {
            value: 'huangpu',
            label: 'Huangpu',
          },
        ],
      },
    ];
    return {
      value,
      options
    }
  },
}
</script>

虚拟列表

虚拟列表的使用方法。


代码事例
vue

<template>
  <fk-cascader
:options="options" :style="{width:'320px'}" placeholder="Please select ..."
              :virtual-list-props="{height:200}" />
</template>

<script>
export default {
  setup() {
    const options = [
      {
        value: 'beijing',
        label: 'Beijing',
        children: [
          {
            value: 'chaoyang',
            label: 'ChaoYang',
            children: [
              {
                value: 'datunli',
                label: 'Datunli',
              },
            ],
          },
          {
            value: 'haidian',
            label: 'Haidian',
          },
          {
            value: 'dongcheng',
            label: 'Dongcheng',
          },
          {
            value: 'xicheng',
            label: 'Xicheng',
            children: [
              {
                value: 'jinrongjie',
                label: 'Jinrongjie',
              },
              {
                value: 'tianqiao',
                label: 'Tianqiao',
              },
            ],
          },
        ],
      },
      {
        value: 'shanghai',
        label: 'Shanghai',
        children: Array.from({length: 1000}).fill(null).map((_, index) => {
          return {
            value: `Option ${index}`,
            label: `Option ${index}`
          }
        })
      },
    ];

    return {
      options
    }
  },
}
</script>

API

<cascader> Props

参数名描述类型默认值版本
path-mode绑定值是否为路径booleanfalse
multiple是否为多选状态(多选模式默认开启搜索)booleanfalse
model-value (v-model)绑定值string | number | Record<string, any> | (string | number | Record<string, any> | (string | number | Record<string, any>)[])[] | undefined-
default-value默认值(非受控状态)string | number | Record<string, any> | (string | number | Record<string, any> | (string | number | Record<string, any>)[])[] | undefined'' \ undefined \ []
options级联选择器的选项CascaderOption[][]
disabled是否禁用booleanfalse
error是否为错误状态booleanfalse
size选择框的大小'mini' | 'small' | 'medium' | 'large''medium'
allow-search是否允许搜索booleanfalse (single) \ true (multiple)
allow-clear是否允许清除booleanfalse
input-value (v-model)输入框的值string-
default-input-value输入框的默认值(非受控状态)string''
popup-visible (v-model)是否显示下拉框boolean-
expand-trigger展开下一级的触发方式'click' | 'hover''click'
default-popup-visible是否默认显示下拉框(非受控状态)booleanfalse
placeholder占位符string-
filter-option自定义选项过滤方法(inputValue: string, option: CascaderOption) => boolean-
popup-container弹出框的挂载容器string | HTMLElement-
max-tag-count多选模式下,最多显示的标签数量。0 表示不限制number0
format-label格式化展示内容(options: CascaderOption[]) => string-
trigger-props下拉菜单的触发器属性TriggerProps-
check-strictly是否开启严格选择模式booleanfalse
load-more数据懒加载函数,传入时开启懒加载功能(option: CascaderOption, done: (children?: CascaderOption[]) => void) => void-1.0.0
loading是否为加载中状态booleanfalse1.0.0
search-option-only-label搜索下拉菜单中的选项是否仅展示标签booleanfalse1.0.0
search-delay触发搜索事件的延迟时间number5001.0.0
field-names自定义 CascaderOption 中的字段CascaderFieldNames-1.0.0
value-key用于确定选项键值的属性名string'value'1.0.0
fallback自定义不存在选项的值的展示boolean | ((value: string | number | Record<string, unknown> | (string | number | Record<string, unknown>)[]) => string)true1.0.0
expand-child是否展开子菜单booleanfalse1.0.0
virtual-list-props传递虚拟列表属性,传入此参数以开启虚拟滚动 VirtualListPropsVirtualListProps-1.0.0
tag-nowrap标签内容不换行booleanfalse1.0.0

<cascader> Events

事件名描述参数
change选中值改变时触发value: string | number | (string | number | (string | number)[])[] | undefined
input-value-change输入值改变时触发value: string
clear点击清除按钮时触发-
search用户搜索时触发value: string
popup-visible-change下拉框的显示状态改变时触发visible: boolean
focus获得焦点时触发ev: FocusEvent
blur失去焦点时触发ev: FocusEvent

<cascader> Slots

插槽名描述参数版本
label选择框的显示内容data: CascaderOption1.0.0
prefix前缀元素-1.0.0
arrow-icon选择框的箭头图标-1.0.0
loading-icon选择框的加载中图标-1.0.0
search-icon选择框的搜索图标-1.0.0
empty选项为空时的显示内容-1.0.0
option选项内容data: CascaderOption1.0.0

<cascader-panel> Props

参数名描述类型默认值版本
path-mode绑定值是否为路径booleanfalse
multiple是否为多选状态(多选模式默认开启搜索)booleanfalse
model-value (v-model)绑定值string | number | Record<string, any> | (string | number | Record<string, any> | (string | number | Record<string, any>)[])[] | undefined-
default-value默认值(非受控状态)string | number | Record<string, any> | (string | number | Record<string, any> | (string | number | Record<string, any>)[])[] | undefined'' \ undefined \ []
options级联选择器的选项CascaderOption[][]
expand-trigger展开下一级的触发方式string'click'
check-strictly是否开启严格选择模式booleanfalse
load-more数据懒加载函数,传入时开启懒加载功能(option: CascaderOption, done: (children?: CascaderOption[]) => void) => void-1.0.0
field-names自定义 CascaderOption 中的字段CascaderFieldNames-1.0.0
value-key用于确定选项键值的属性名string'value'1.0.0
expand-child是否展开子菜单booleanfalse1.0.0

<cascader-panel> Events

事件名描述参数
change选中值改变时触发value: string | number | (string | number | (string | number)[])[] | undefined

<cascader-panel> Slots

插槽名描述参数版本
empty选项为空时的显示内容-1.0.0

CascaderOption

参数名描述类型默认值版本
value选项值,2.29.0 版本支持对象string | number | Record<string, any>-
label选项文本string-
render自定义渲染RenderFunction-
disabled是否禁用booleanfalse
tagProps展示的标签属性TagProps-1.0.0
children下一级选项CascaderOption[]-
isLeaf是否是叶子节点booleanfalse

基于 MIT 许可发布