Skip to content

Commit 3a6cc6a

Browse files
committed
refactor: cascader
1 parent 616478b commit 3a6cc6a

File tree

12 files changed

+182
-74
lines changed

12 files changed

+182
-74
lines changed

components/cascader/demo/custom-render.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ const options: CascaderProps['options'] = [
7777
];
7878
export default defineComponent({
7979
setup() {
80-
const handleAreaClick = (e: Event, label: string, option: Option) => {
80+
const handleAreaClick = (e: Event, label: string, option: CascaderProps['options'][number]) => {
8181
e.stopPropagation();
8282
console.log('clicked', label, option);
8383
};

components/cascader/demo/custom-trigger.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export default defineComponent({
7171
const value = ref<string[]>([]);
7272
const text = ref<string>('Unselect');
7373
74-
const onChange = (_value: string, selectedOptions: Option[]) => {
74+
const onChange: CascaderProps['onChange'] = (_value, selectedOptions) => {
7575
text.value = selectedOptions.map(o => o.label).join(', ');
7676
};
7777

components/cascader/demo/index.vue

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<lazy />
1212
<fields-name />
1313
<suffix />
14+
<multipleVue />
1415
</demo-sort>
1516
</template>
1617
<script>
@@ -25,6 +26,7 @@ import Search from './search.vue';
2526
import Size from './size.vue';
2627
import FieldsName from './fields-name.vue';
2728
import Suffix from './suffix.vue';
29+
import multipleVue from './multiple.vue';
2830
2931
import CN from '../index.zh-CN.md';
3032
import US from '../index.en-US.md';
@@ -44,6 +46,7 @@ export default defineComponent({
4446
Size,
4547
FieldsName,
4648
Suffix,
49+
multipleVue,
4750
},
4851
});
4952
</script>

components/cascader/demo/lazy.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default defineComponent({
4545
},
4646
]);
4747
48-
const loadData = (selectedOptions: Option[]) => {
48+
const loadData: CascaderProps['loadData'] = selectedOptions => {
4949
const targetOption = selectedOptions[selectedOptions.length - 1];
5050
targetOption.loading = true;
5151

components/cascader/demo/multiple.vue

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<docs>
2+
---
3+
order: 5.1
4+
version: 3.0.0
5+
title:
6+
zh-CN: 多选
7+
en-US: Multiple
8+
---
9+
10+
## zh-CN
11+
12+
一次性选择多个选项。
13+
14+
## en-US
15+
16+
Select multiple options
17+
</docs>
18+
<template>
19+
<a-cascader
20+
v-model:value="value"
21+
style="width: 233px"
22+
multiple
23+
max-tag-count="responsive"
24+
:options="options"
25+
placeholder="Please select"
26+
></a-cascader>
27+
</template>
28+
<script lang="ts">
29+
import { defineComponent, ref } from 'vue';
30+
import type { CascaderProps } from 'ant-design-vue';
31+
const options: CascaderProps['options'] = [
32+
{
33+
label: 'Light',
34+
value: 'light',
35+
children: new Array(20)
36+
.fill(null)
37+
.map((_, index) => ({ label: `Number ${index}`, value: index })),
38+
},
39+
{
40+
label: 'Bamboo',
41+
value: 'bamboo',
42+
children: [
43+
{
44+
label: 'Little',
45+
value: 'little',
46+
children: [
47+
{
48+
label: 'Toy Fish',
49+
value: 'fish',
50+
},
51+
{
52+
label: 'Toy Cards',
53+
value: 'cards',
54+
},
55+
{
56+
label: 'Toy Bird',
57+
value: 'bird',
58+
},
59+
],
60+
},
61+
],
62+
},
63+
];
64+
export default defineComponent({
65+
setup() {
66+
return {
67+
value: ref<string[]>([]),
68+
options,
69+
};
70+
},
71+
});
72+
</script>

components/cascader/demo/search.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Search and select options directly.
2828
<script lang="ts">
2929
import { defineComponent, ref } from 'vue';
3030
import type { CascaderProps } from 'ant-design-vue';
31+
import type { ShowSearchType } from 'ant-design-vue/es/cascader';
3132
const options: CascaderProps['options'] = [
3233
{
3334
value: 'zhejiang',
@@ -69,7 +70,7 @@ const options: CascaderProps['options'] = [
6970
];
7071
export default defineComponent({
7172
setup() {
72-
const filter = (inputValue: string, path: Option[]) => {
73+
const filter: ShowSearchType['filter'] = (inputValue, path) => {
7374
return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
7475
};
7576

components/cascader/index.en-US.md

+29-24
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,34 @@ Cascade selection box.
1919
<a-cascader :options="options" v-model:value="value" />
2020
```
2121

22-
| Property | Description | Type | Default |
23-
| --- | --- | --- | --- |
24-
| allowClear | whether allow clear | boolean | true |
25-
| autofocus | get focus when component mounted | boolean | false |
26-
| changeOnSelect | change value on each selection if set to true, see above demo for details | boolean | false |
27-
| defaultValue | initial selected value | string\[] \| number\[] | \[] |
28-
| disabled | whether disabled select | boolean | false |
29-
| displayRender | render function of displaying selected options, you can use #displayRender="{labels, selectedOptions}" | `({labels, selectedOptions}) => VNode` | `labels => labels.join(' / ')` |
30-
| expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' |
31-
| fieldNames | custom field name for label and value and children | object | `{ label: 'label', value: 'value', children: 'children' }` |
32-
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. | Function(triggerNode) | () => document.body |
33-
| loadData | To load option lazily, and it cannot work with `showSearch` | `(selectedOptions) => void` | - |
34-
| notFoundContent | Specify content to show when no result matches. | string | 'Not Found' |
35-
| options | data options of cascade | [Option](#option)[] | - |
36-
| placeholder | input placeholder | string | 'Please select' |
37-
| popupClassName | additional className of popup overlay | string | - |
38-
| popupStyle | additional style of popup overlay | object | {} |
39-
| popupPlacement | use preset popup align config from builtinPlacements:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` |
40-
| popupVisible | set visible of cascader popup | boolean | - |
41-
| showSearch | Whether show search input in single mode. | boolean \| [object](#showsearch) | false |
42-
| size | input size, one of `large` `default` `small` | string | `default` |
43-
| suffixIcon | The custom suffix icon | string \| VNode \| slot | - |
44-
| value(v-model) | selected value | string\[] \| number\[] | - |
22+
| Property | Description | Type | Default | Version |
23+
| --- | --- | --- | --- | --- |
24+
| allowClear | whether allow clear | boolean | true | |
25+
| autofocus | get focus when component mounted | boolean | false | |
26+
| changeOnSelect | change value on each selection if set to true, see above demo for details | boolean | false | |
27+
| disabled | whether disabled select | boolean | false | |
28+
| displayRender | render function of displaying selected options, you can use #displayRender="{labels, selectedOptions}" | `({labels, selectedOptions}) => VNode` | `labels => labels.join(' / ')` | |
29+
| expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' | |
30+
| fieldNames | custom field name for label and value and children | object | `{ label: 'label', value: 'value', children: 'children' }` | |
31+
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. | Function(triggerNode) | () => document.body | |
32+
| loadData | To load option lazily, and it cannot work with `showSearch` | `(selectedOptions) => void` | - | |
33+
| notFoundContent | Specify content to show when no result matches. | string \| slot | 'Not Found' | |
34+
| options | data options of cascade | [Option](#option)[] | - | |
35+
| placeholder | input placeholder | string | 'Please select' | |
36+
| showSearch | Whether show search input in single mode. | boolean \| [object](#showsearch) | false | |
37+
| size | input size, one of `large` `default` `small` | string | `default` | |
38+
| suffixIcon | The custom suffix icon | string \| VNode \| slot | - | |
39+
| value(v-model) | selected value | string\[] \| number\[] | - | |
40+
| expandIcon | Customize the current item expand icon | slot | - | 3.0 |
41+
| maxTagCount | Max tag count to show. `responsive` will cost render performance | number \| `responsive` | - | 3.0 |
42+
| maxTagPlaceholder | Placeholder for not showing tags | v-slot \| function(omittedValues) | - | 3.0 |
43+
| dropdownClassName | additional className of popup overlay | string | - | 3.0 |
44+
| dropdownStyle | additional style of popup overlay | CSSProperties | {} | 3.0 |
45+
| open | set visible of cascader popup | boolean | - | 3.0 |
46+
| placement | use preset popup align config from builtinPlacements:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | 3.0 |
47+
| tagRender | Customize tag render when `multiple` | slot | - | 3.0 |
48+
| multiple | Support multiple or not | boolean | - | 3.0 |
49+
| searchValue | Set search value,Need work with `showSearch` | string | - | 3.0 |
4550

4651
### showSearch
4752

@@ -60,7 +65,7 @@ Fields in `showSearch`:
6065
| Events Name | Description | Arguments | version |
6166
| --- | --- | --- | --- | --- |
6267
| change | callback when finishing cascader select | `(value, selectedOptions) => void` | - | |
63-
| popupVisibleChange | callback when popup shown or hidden | `(value) => void` | - | |
68+
| dropdownVisibleChange | callback when popup shown or hidden | `(value) => void` | - | 3.0 |
6469
| search | callback when input value change | `(value) => void` | - | 1.5.4 |
6570

6671
### Option

components/cascader/index.tsx

+2-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type { ValueType } from '../vc-cascader/Cascader';
2424
// - Hover opacity style
2525
// - Search filter match case
2626

27-
export { BaseOptionType, DefaultOptionType };
27+
export type { BaseOptionType, DefaultOptionType, ShowSearchType };
2828

2929
export type FieldNamesType = FieldNames;
3030

@@ -134,11 +134,6 @@ const Cascader = defineComponent({
134134
// =================== Warning =====================
135135
if (process.env.NODE_ENV !== 'production') {
136136
watchEffect(() => {
137-
devWarning(
138-
props.popupClassName === undefined,
139-
'Cascader',
140-
'`popupClassName` is deprecated. Please use `dropdownClassName` instead.',
141-
);
142137
devWarning(
143138
!props.multiple || !props.displayRender || !slots.displayRender,
144139
'Cascader',
@@ -269,6 +264,7 @@ const Cascader = defineComponent({
269264
checkable: () => <span class={`${cascaderPrefixCls.value}-checkbox-inner`} />,
270265
}}
271266
displayRender={props.displayRender || slots.displayRender}
267+
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
272268
onChange={handleChange}
273269
onBlur={handleBlur}
274270
v-slots={slots}

components/cascader/index.zh-CN.md

+35-29
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,35 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
2020
<a-cascader :options="options" v-model:value="value" />
2121
```
2222

23-
| 参数 | 说明 | 类型 | 默认值 |
24-
| --- | --- | --- | --- |
25-
| allowClear | 是否支持清除 | boolean | true |
26-
| autofocus | 自动获取焦点 | boolean | false |
27-
| changeOnSelect | 当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | boolean | false |
28-
| defaultValue | 默认的选中项 | string\[] \| number\[] | \[] |
29-
| disabled | 禁用 | boolean | false |
30-
| displayRender | 选择后展示的渲染函数,可使用 #displayRender="{labels, selectedOptions}" | `({labels, selectedOptions}) => VNode` | `labels => labels.join(' / ')` |
31-
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' |
32-
| fieldNames | 自定义 options 中 label name children 的字段 | object | `{ label: 'label', value: 'value', children: 'children' }` |
33-
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body |
34-
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | `(selectedOptions) => void` | - |
35-
| notFoundContent | 当下拉列表为空时显示的内容 | string | 'Not Found' |
36-
| options | 可选项数据源 | [Option](#option)[] | - |
37-
| placeholder | 输入框占位文本 | string | '请选择' |
38-
| popupClassName | 自定义浮层类名 | string | - |
39-
| popupStyle | 自定义浮层样式 | object | {} |
40-
| popupPlacement | 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` | Enum | `bottomLeft` |
41-
| popupVisible | 控制浮层显隐 | boolean | - |
42-
| showSearch | 在选择框中显示搜索框 | boolean \| [object](#showsearch) | false |
43-
| size | 输入框大小,可选 `large` `default` `small` | string | `default` |
44-
| suffixIcon | 自定义的选择框后缀图标 | string \| VNode \| slot | - |
45-
| value(v-model) | 指定选中项 | string\[] \| number\[] | - |
23+
| 参数 | 说明 | 类型 | 默认值 | Version |
24+
| --- | --- | --- | --- | --- |
25+
| allowClear | 是否支持清除 | boolean | true | |
26+
| autofocus | 自动获取焦点 | boolean | false | |
27+
| changeOnSelect | 当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | boolean | false | |
28+
| defaultValue | 默认的选中项 | string\[] \| number\[] | \[] | |
29+
| disabled | 禁用 | boolean | false | |
30+
| displayRender | 选择后展示的渲染函数,可使用 #displayRender="{labels, selectedOptions}" | `({labels, selectedOptions}) => VNode` | `labels => labels.join(' / ')` | |
31+
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' | |
32+
| fieldNames | 自定义 options 中 label name children 的字段 | object | `{ label: 'label', value: 'value', children: 'children' }` | |
33+
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body | |
34+
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | `(selectedOptions) => void` | - | |
35+
| notFoundContent | 当下拉列表为空时显示的内容 | string \| slot | 'Not Found' | |
36+
| options | 可选项数据源 | [Option](#option)[] | - | |
37+
| placeholder | 输入框占位文本 | string | '请选择' | |
38+
| showSearch | 在选择框中显示搜索框 | boolean \| [object](#showsearch) | false | |
39+
| size | 输入框大小,可选 `large` `default` `small` | string | `default` | |
40+
| suffixIcon | 自定义的选择框后缀图标 | string \| VNode \| slot | - | |
41+
| value(v-model) | 指定选中项 | string\[] \| number\[] | - | |
42+
| expandIcon | 自定义次级菜单展开图标 | slot | - | 3.0 |
43+
| maxTagCount | 最多显示多少个 tag,响应式模式会对性能产生损耗 | number \| `responsive` | - | 3.0 |
44+
| maxTagPlaceholder | 隐藏 tag 时显示的内容 | v-slot \| function(omittedValues) | - | 3.0 |
45+
| dropdownClassName | 自定义浮层类名 | string | - | 3.0 |
46+
| dropdownStyle | 自定义浮层样式 | CSSProperties | {} | 3.0 |
47+
| open | 控制浮层显隐 | boolean | - | 3.0 |
48+
| placement | 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | 3.0 |
49+
| tagRender | 自定义 tag 内容,多选时生效 | (props) => ReactNode | - | 3.0 |
50+
| multiple | 支持多选节点 | boolean | - | 3.0 |
51+
| searchValue | 设置搜索的值,需要与 `showSearch` 配合使用 | string | - | 3.0 |
4652

4753
### showSearch
4854

@@ -58,18 +64,18 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
5864

5965
### 事件
6066

61-
| 事件名称 | 说明 | 回调参数 | 版本 |
62-
| ------------------ | ------------------- | ---------------------------------- | ---- | ----- |
63-
| change | 选择完成后的回调 | `(value, selectedOptions) => void` | - | |
64-
| popupVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - | |
65-
| search | 输入框变化时的回调 | `(value) => void` | - | 1.5.4 |
67+
| 事件名称 | 说明 | 回调参数 | 版本 |
68+
| --------------------- | ---------------------- | ---------------------------------- | ---- | --- |
69+
| change | 选择完成后的回调 | `(value, selectedOptions) => void` | - | |
70+
| dropdownVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - | 3.0 |
71+
| search | 监听搜索,返回输入的值 | `(value) => void` | - | 3.0 |
6672

6773
### Option
6874

6975
```ts
7076
interface Option {
7177
value: string | number;
72-
label?: VNode;
78+
label?: any;
7379
disabled?: boolean;
7480
children?: Option[];
7581
}

0 commit comments

Comments
 (0)