diff --git a/packages/vant/src/cascader/Cascader.tsx b/packages/vant/src/cascader/Cascader.tsx
index fe62dfe5b..20651d7a8 100644
--- a/packages/vant/src/cascader/Cascader.tsx
+++ b/packages/vant/src/cascader/Cascader.tsx
@@ -258,6 +258,9 @@ export default defineComponent({
unselected: !selected,
})}
>
+ {slots['options-top']
+ ? slots['options-top']({ activeTab: activeTab.value })
+ : null}
{renderOptions(options, selected, tabIndex)}
);
@@ -278,7 +281,6 @@ export default defineComponent({
);
updateTabs();
-
watch(() => props.options, updateTabs, { deep: true });
watch(
() => props.modelValue,
diff --git a/packages/vant/src/cascader/README.md b/packages/vant/src/cascader/README.md
index 0759d050d..ed3658163 100644
--- a/packages/vant/src/cascader/README.md
+++ b/packages/vant/src/cascader/README.md
@@ -197,6 +197,54 @@ export default {
};
```
+### Custom Content
+
+```html
+
+
+ Current level {{activeTab}}
+
+
+```
+
+```js
+import { ref } from 'vue';
+
+export default {
+ setup() {
+ const code = ref('');
+ const fieldNames = {
+ text: 'name',
+ value: 'code',
+ children: 'items',
+ };
+ const options = [
+ {
+ name: 'Zhejiang',
+ code: '330000',
+ items: [{ name: 'Hangzhou', code: '330100' }],
+ },
+ {
+ name: 'Jiangsu',
+ code: '320000',
+ items: [{ name: 'Nanjing', code: '320100' }],
+ },
+ ];
+
+ return {
+ code,
+ options,
+ fieldNames,
+ };
+ },
+};
+```
+
## API
### Props
@@ -239,6 +287,7 @@ export default {
| --- | --- | --- |
| title | Custom title | - |
| option `v3.1.4` | Custom option text | _{ option: Option, selected: boolean }_ |
+| options-top | Custom the content above options | - |
### Types
diff --git a/packages/vant/src/cascader/README.zh-CN.md b/packages/vant/src/cascader/README.zh-CN.md
index 1960fe577..4f3a3a81d 100644
--- a/packages/vant/src/cascader/README.zh-CN.md
+++ b/packages/vant/src/cascader/README.zh-CN.md
@@ -207,6 +207,54 @@ export default {
};
```
+### 自定义选项上方内容
+
+```html
+
+
+ 当前为第{{ tabIndex }}级
+
+
+```
+
+```js
+import { ref } from 'vue';
+
+export default {
+ setup() {
+ const code = ref('');
+ const fieldNames = {
+ text: 'name',
+ value: 'code',
+ children: 'items',
+ };
+ const options = [
+ {
+ name: '浙江省',
+ code: '330000',
+ items: [{ name: '杭州市', code: '330100' }],
+ },
+ {
+ name: '江苏省',
+ code: '320000',
+ items: [{ name: '南京市', code: '320100' }],
+ },
+ ];
+
+ return {
+ code,
+ options,
+ fieldNames,
+ };
+ },
+};
+```
+
## API
### Props
@@ -247,10 +295,11 @@ export default {
### Slots
-| 名称 | 说明 | 参数 |
-| --------------- | -------------- | --------------------------------------- |
-| title | 自定义顶部标题 | - |
+| 名称 | 说明 | 参数 |
+| --- | --- | --- |
+| title | 自定义顶部标题 | - |
| option `v3.1.4` | 自定义选项文字 | _{ option: Option, selected: boolean }_ |
+| options-top | 自定义选项上方的内容 | - |
### 类型定义
diff --git a/packages/vant/src/cascader/demo/index.vue b/packages/vant/src/cascader/demo/index.vue
index 029e4cef6..041c824e7 100644
--- a/packages/vant/src/cascader/demo/index.vue
+++ b/packages/vant/src/cascader/demo/index.vue
@@ -27,6 +27,7 @@ const t = useTranslate({
{ text: '宁波市', value: '330200' },
],
customFieldNames: '自定义字段名',
+ customContent: '自定义内容',
},
'en-US': {
area: 'Area',
@@ -46,6 +47,7 @@ const t = useTranslate({
{ text: 'Ningbo', value: '330200' },
],
customFieldNames: 'Custom Field Names',
+ customContent: 'Custom Content',
},
});
@@ -54,6 +56,7 @@ type StateItem = {
value: string | number | null;
result: string;
options?: CascaderOption[];
+ tabIndex?: number;
};
const baseState = reactive({
@@ -84,6 +87,12 @@ const fieldNames = {
children: 'items',
};
+const customContentState = reactive({
+ show: false,
+ value: null,
+ result: '',
+});
+
const customFieldOptions = computed(() => {
const options = deepClone(t('options'));
const adjustFieldName = (item: CascaderOption) => {
@@ -234,4 +243,35 @@ const onFinish = (
/>
+
+
+
+
+
+
+ 当前为第{{ activeTab }}级
+
+
+
+
diff --git a/packages/vant/src/cascader/test/index.spec.ts b/packages/vant/src/cascader/test/index.spec.ts
index 64346f8dd..4869914af 100644
--- a/packages/vant/src/cascader/test/index.spec.ts
+++ b/packages/vant/src/cascader/test/index.spec.ts
@@ -241,3 +241,23 @@ test('should allow to custom the color of option', async () => {
const option = wrapper.find('.van-cascader__option');
expect(option.style.color).toEqual('red');
});
+
+test(' should allow more custom content', async () => {
+ const wrapper = mount(Cascader, {
+ slots: {
+ 'options-top': ({ activeTab }) => activeTab,
+ },
+ props: {
+ options,
+ },
+ });
+ await later();
+ wrapper
+ .findAll('.van-cascader__options')[0]
+ .find('.van-cascader__option')
+ .trigger('click');
+ wrapper.vm.$nextTick(() => {
+ const top = wrapper.find('.van-tab__pane');
+ expect(top.text()).toBe('1');
+ });
+});