diff --git a/docs/en-US/component/cascader.md b/docs/en-US/component/cascader.md
index bb5cc3424f..c7f8a174aa 100644
--- a/docs/en-US/component/cascader.md
+++ b/docs/en-US/component/cascader.md
@@ -168,6 +168,16 @@ cascader/check-on-click-node
:::
+## Show Checked Strategy
+
+Control how selected values are displayed in multiple selection mode.
+
+:::demo In multiple selection mode, you can use `show-checked-strategy` to control how selected values are displayed. The default strategy is `child`, which shows all selected child nodes. The `parent` strategy only shows parent nodes when all their children are selected.
+
+cascader/show-checked-strategy
+
+:::
+
## Cascader API
### Cascader Attributes
@@ -202,6 +212,7 @@ cascader/check-on-click-node
| fallback-placements ^(2.8.1) | list of possible positions for Tooltip [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[arrary]`Placement[]` | — |
| placement ^(2.8.1) | position of dropdown | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom-start |
| popper-append-to-body ^(deprecated) | whether to append the popper menu to body. If the positioning of the popper is wrong, you can try to set this prop to false | ^[boolean] | true |
+| show-checked-strategy ^(2.10.5) | strategy for displaying checked nodes in multiple selection mode. Use `parent` when you want things tidy. Use `child` when every single item matters | ^[enum]`'parent' \| 'child'` | child |
### Cascader Events
diff --git a/docs/examples/cascader/show-checked-strategy.vue b/docs/examples/cascader/show-checked-strategy.vue
new file mode 100644
index 0000000000..e185757f7c
--- /dev/null
+++ b/docs/examples/cascader/show-checked-strategy.vue
@@ -0,0 +1,314 @@
+
+
+
Strategy: child (default, show all selected child nodes)
+
+
+
+
+
+ Strategy: parent (show only parent nodes when all children are selected)
+
+
+
+
+
+
diff --git a/packages/components/cascader/src/cascader.ts b/packages/components/cascader/src/cascader.ts
index 3779716094..43b03f72a3 100644
--- a/packages/components/cascader/src/cascader.ts
+++ b/packages/components/cascader/src/cascader.ts
@@ -142,6 +142,15 @@ export const cascaderProps = buildProps({
type: Boolean,
default: true,
},
+ /**
+ * @description Use `parent` when you want things tidy (like "Entire Collection" instead of listing 100 items)
+ * Use `child` when every single item matters (like important settings)
+ */
+ showCheckedStrategy: {
+ type: String,
+ values: ['parent', 'child'],
+ default: 'child',
+ },
/**
* @description whether to check or uncheck node when clicking on the node
*/
diff --git a/packages/components/cascader/src/cascader.vue b/packages/components/cascader/src/cascader.vue
index a3e9dbdb22..70bc8ec15d 100644
--- a/packages/components/cascader/src/cascader.vue
+++ b/packages/components/cascader/src/cascader.vue
@@ -259,8 +259,8 @@ const popperOptions: Partial = {
name: 'arrowPosition',
enabled: true,
phase: 'main',
- fn: ({ state }) => {
- const { modifiersData, placement } = state as any
+ fn: ({ state }: any) => {
+ const { modifiersData, placement } = state
if (['right', 'left', 'bottom', 'top'].includes(placement)) return
if (modifiersData.arrow) {
modifiersData.arrow.x = 35
@@ -447,10 +447,27 @@ const deleteTag = (tag: Tag) => {
emit('removeTag', node.valueByOption)
}
+const getStrategyCheckedNodes = (): CascaderNode[] => {
+ switch (props.showCheckedStrategy) {
+ case 'child':
+ return checkedNodes.value
+ case 'parent': {
+ const clickedNodes = getCheckedNodes(false)
+ const clickedNodesValue = clickedNodes!.map((o) => o.value)
+ const parentNodes = clickedNodes!.filter(
+ (o) => !o.parent || !clickedNodesValue.includes(o.parent.value)
+ )
+ return parentNodes
+ }
+ default:
+ return []
+ }
+}
+
const calculatePresentTags = () => {
if (!multiple.value) return
- const nodes = checkedNodes.value
+ const nodes = getStrategyCheckedNodes()
const tags: Tag[] = []
const allTags: Tag[] = []