diff --git a/src/cascader/Cascader.tsx b/src/cascader/Cascader.tsx
index 21cbca109..57249578e 100644
--- a/src/cascader/Cascader.tsx
+++ b/src/cascader/Cascader.tsx
@@ -59,11 +59,7 @@ export default defineComponent({
activeTab: 0,
});
- const {
- text: textKey,
- value: valueKey,
- children: childrenKey,
- } = extend(
+ const { text: textKey, value: valueKey, children: childrenKey } = extend(
{
text: 'text',
value: 'value',
@@ -210,39 +206,52 @@ export default defineComponent({
);
+ const renderOption = (
+ option: CascaderOption,
+ selectedOption: CascaderOption | null,
+ tabIndex: number
+ ) => {
+ const selected =
+ selectedOption && option[valueKey] === selectedOption[valueKey];
+ const color = option.color || (selected ? props.activeColor : undefined);
+
+ const Text = slots.option ? (
+ slots.option({ option, selected })
+ ) : (
+ {option[textKey]}
+ );
+
+ return (
+
onSelect(option, tabIndex)}
+ >
+ {Text}
+ {selected ? (
+
+ ) : null}
+
+ );
+ };
+
const renderOptions = (
options: CascaderOption[],
selectedOption: CascaderOption | null,
tabIndex: number
- ) => {
- const renderOption = (option: CascaderOption) => {
- const isSelected =
- selectedOption && option[valueKey] === selectedOption[valueKey];
- const color =
- option.color || (isSelected ? props.activeColor : undefined);
-
- return (
- onSelect(option, tabIndex)}
- >
- {option[textKey]}
- {isSelected ? (
-
- ) : null}
-
- );
- };
-
- return {options.map(renderOption)}
;
- };
+ ) => (
+
+ {options.map((option) =>
+ renderOption(option, selectedOption, tabIndex)
+ )}
+
+ );
const renderTab = (tab: CascaderTab, tabIndex: number) => {
const { options, selectedOption } = tab;
diff --git a/src/cascader/README.md b/src/cascader/README.md
index fdf2b9822..8f8af5efb 100644
--- a/src/cascader/README.md
+++ b/src/cascader/README.md
@@ -235,9 +235,10 @@ export default {
### Slots
-| Name | Description |
-| ----- | ------------ |
-| title | Custom title |
+| Name | Description | SlotProps |
+| --- | --- | --- |
+| title | Custom title | - |
+| option `v3.1.4` | Custom option text | _{ option: Option, selected: boolean }_ |
### CSS Variables
diff --git a/src/cascader/README.zh-CN.md b/src/cascader/README.zh-CN.md
index 869718f90..b53ad03bb 100644
--- a/src/cascader/README.zh-CN.md
+++ b/src/cascader/README.zh-CN.md
@@ -247,9 +247,10 @@ export default {
### Slots
-| 名称 | 说明 |
-| ----- | -------------- |
-| title | 自定义顶部标题 |
+| 名称 | 说明 | 参数 |
+| --------------- | -------------- | --------------------------------------- |
+| title | 自定义顶部标题 | - |
+| option `v3.1.4` | 自定义选项文字 | _{ option: Option, selected: boolean }_ |
### 样式变量
diff --git a/src/cascader/test/__snapshots__/index.spec.ts.snap b/src/cascader/test/__snapshots__/index.spec.ts.snap
index 4179cd931..bca975355 100644
--- a/src/cascader/test/__snapshots__/index.spec.ts.snap
+++ b/src/cascader/test/__snapshots__/index.spec.ts.snap
@@ -5,6 +5,12 @@ exports[`should change close icon when using close-icon prop 1`] = `
`;
+exports[`should render option slot correctly 1`] = `
+
+ Custom Option foo
+
+`;
+
exports[`should render title slot correctly 1`] = `
Custom Title
diff --git a/src/cascader/test/index.spec.ts b/src/cascader/test/index.spec.ts
index ed3951adf..62a9d78cf 100644
--- a/src/cascader/test/index.spec.ts
+++ b/src/cascader/test/index.spec.ts
@@ -88,6 +88,20 @@ test('should render title slot correctly', () => {
expect(wrapper.find('.van-cascader__title').html()).toMatchSnapshot();
});
+test('should render option slot correctly', async () => {
+ const option = { value: '1', text: 'foo' };
+ const wrapper = mount(Cascader, {
+ props: {
+ options: [option],
+ },
+ slots: {
+ option: ({ option }) => `Custom Option ${option.text}`,
+ },
+ });
+ await later();
+ expect(wrapper.find('.van-cascader__option').html()).toMatchSnapshot();
+});
+
// TODO
// test('should select correct option when value changed', async () => {
// const wrapper = mount(Cascader, {