mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-21 05:49:16 +08:00
feat(PickerGroup): the tab of PickerGroup supports controlled mode (#11771)
* feat(PickerGroup): add method to set the active of tab * chore: update * chore: format code * chore: update * chore: update * docs: update docs
This commit is contained in:
parent
e0ae206c89
commit
3dabce8e98
@ -1,15 +1,17 @@
|
|||||||
import {
|
import { defineComponent, type InjectionKey, type ExtractPropTypes } from 'vue';
|
||||||
ref,
|
|
||||||
defineComponent,
|
|
||||||
type InjectionKey,
|
|
||||||
type ExtractPropTypes,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import { extend, pick, makeArrayProp, createNamespace } from '../utils';
|
import {
|
||||||
|
pick,
|
||||||
|
extend,
|
||||||
|
makeArrayProp,
|
||||||
|
makeNumericProp,
|
||||||
|
createNamespace,
|
||||||
|
} from '../utils';
|
||||||
|
|
||||||
// Composables
|
// Composables
|
||||||
import { useChildren } from '@vant/use';
|
import { useChildren } from '@vant/use';
|
||||||
|
import { useSyncPropRef } from '../composables/use-sync-prop-ref';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { Tab } from '../tab';
|
import { Tab } from '../tab';
|
||||||
@ -28,6 +30,7 @@ export const PICKER_GROUP_KEY: InjectionKey<PickerGroupProvide> = Symbol(name);
|
|||||||
export const pickerGroupProps = extend(
|
export const pickerGroupProps = extend(
|
||||||
{
|
{
|
||||||
tabs: makeArrayProp<string>(),
|
tabs: makeArrayProp<string>(),
|
||||||
|
activeTab: makeNumericProp(0),
|
||||||
nextStepText: String,
|
nextStepText: String,
|
||||||
},
|
},
|
||||||
pickerToolbarProps
|
pickerToolbarProps
|
||||||
@ -40,20 +43,23 @@ export default defineComponent({
|
|||||||
|
|
||||||
props: pickerGroupProps,
|
props: pickerGroupProps,
|
||||||
|
|
||||||
emits: ['confirm', 'cancel'],
|
emits: ['confirm', 'cancel', 'update:activeTab'],
|
||||||
|
|
||||||
setup(props, { emit, slots }) {
|
setup(props, { emit, slots }) {
|
||||||
const activeTab = ref(0);
|
const activeTab = useSyncPropRef(
|
||||||
|
() => props.activeTab,
|
||||||
|
(value) => emit('update:activeTab', value)
|
||||||
|
);
|
||||||
const { children, linkChildren } = useChildren(PICKER_GROUP_KEY);
|
const { children, linkChildren } = useChildren(PICKER_GROUP_KEY);
|
||||||
|
|
||||||
linkChildren();
|
linkChildren();
|
||||||
|
|
||||||
const showNextButton = () =>
|
const showNextButton = () =>
|
||||||
activeTab.value < props.tabs.length - 1 && props.nextStepText;
|
+activeTab.value < props.tabs.length - 1 && props.nextStepText;
|
||||||
|
|
||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
if (showNextButton()) {
|
if (showNextButton()) {
|
||||||
activeTab.value++;
|
activeTab.value = +activeTab.value + 1;
|
||||||
} else {
|
} else {
|
||||||
emit(
|
emit(
|
||||||
'confirm',
|
'confirm',
|
||||||
|
@ -56,11 +56,13 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
const currentDate = ref(['2022', '06', '01']);
|
const currentDate = ref(['2022', '06', '01']);
|
||||||
const currentTime = ref(['12', '00']);
|
const currentTime = ref(['12', '00']);
|
||||||
|
|
||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
showToast(
|
showToast(
|
||||||
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
showToast('cancel');
|
showToast('cancel');
|
||||||
};
|
};
|
||||||
@ -70,6 +72,8 @@ export default {
|
|||||||
maxDate: new Date(2025, 5, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentDate,
|
currentDate,
|
||||||
currentTime,
|
currentTime,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -104,11 +108,13 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
const currentDate = ref(['2022', '06', '01']);
|
const currentDate = ref(['2022', '06', '01']);
|
||||||
const currentTime = ref(['12', '00']);
|
const currentTime = ref(['12', '00']);
|
||||||
|
|
||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
showToast(
|
showToast(
|
||||||
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
showToast('cancel');
|
showToast('cancel');
|
||||||
};
|
};
|
||||||
@ -118,6 +124,8 @@ export default {
|
|||||||
maxDate: new Date(2025, 5, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentDate,
|
currentDate,
|
||||||
currentTime,
|
currentTime,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -155,6 +163,7 @@ export default {
|
|||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
showToast(`${startDate.value.join('/')} ${endDate.value.join('/')}`);
|
showToast(`${startDate.value.join('/')} ${endDate.value.join('/')}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
showToast('cancel');
|
showToast('cancel');
|
||||||
};
|
};
|
||||||
@ -164,6 +173,8 @@ export default {
|
|||||||
maxDate: new Date(2025, 5, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
endDate,
|
endDate,
|
||||||
startDate,
|
startDate,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -197,6 +208,7 @@ export default {
|
|||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
showToast(`${startTime.value.join(':')} ${endTime.value.join(':')}`);
|
showToast(`${startTime.value.join(':')} ${endTime.value.join(':')}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
showToast('cancel');
|
showToast('cancel');
|
||||||
};
|
};
|
||||||
@ -204,6 +216,72 @@ export default {
|
|||||||
return {
|
return {
|
||||||
endTime,
|
endTime,
|
||||||
startTime,
|
startTime,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Controlled Mode
|
||||||
|
|
||||||
|
Supports both uncontrolled and controlled modes:
|
||||||
|
|
||||||
|
- When `v-model:active-tab` is not bound, the PickerGroup component completely controls the `tab` switching.
|
||||||
|
- When `v-model:active-tab` is bound, PickerGroup supports controlled mode, and the `tab` switching is controlled by both the `v-model:active-tab` value and the component itself.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-button type="primary" @click="setActiveTab">
|
||||||
|
toggle tab, current {{ activeTab }}
|
||||||
|
</van-button>
|
||||||
|
<van-picker-group
|
||||||
|
v-model:active-tab="activeTab"
|
||||||
|
title="Title"
|
||||||
|
:tabs="['Date', 'Time']"
|
||||||
|
@confirm="onConfirm"
|
||||||
|
@cancel="onCancel"
|
||||||
|
>
|
||||||
|
<van-date-picker
|
||||||
|
v-model="currentDate"
|
||||||
|
:min-date="minDate"
|
||||||
|
:max-date="maxDate"
|
||||||
|
/>
|
||||||
|
<van-time-picker v-model="currentTime" />
|
||||||
|
</van-picker-group>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { showToast } from 'vant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const activeTab = ref(0);
|
||||||
|
const currentDate = ref(['2022', '06', '01']);
|
||||||
|
const currentTime = ref(['12', '00']);
|
||||||
|
|
||||||
|
const setActiveTab = () => {
|
||||||
|
activeTab.value = activeTab.value ? 0 : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onConfirm = () => {
|
||||||
|
showToast(
|
||||||
|
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const onCancel = () => {
|
||||||
|
showToast('cancel');
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
minDate: new Date(2020, 0, 1),
|
||||||
|
maxDate: new Date(2025, 5, 1),
|
||||||
|
activeTab,
|
||||||
|
currentDate,
|
||||||
|
currentTime,
|
||||||
|
setActiveTab,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -213,13 +291,14 @@ export default {
|
|||||||
|
|
||||||
### Props
|
### Props
|
||||||
|
|
||||||
| Attribute | Description | Type | Default |
|
| Attribute | Description | Type | Default |
|
||||||
| ----------------------- | ------------------------ | ---------- | --------- |
|
| --- | --- | --- | --- |
|
||||||
| tabs | Titles of tabs | _string[]_ | `[]` |
|
| v-model:active-tab | Set index of active tab | _number \| string_ | `0` |
|
||||||
| title | Toolbar title | _string_ | `''` |
|
| tabs | Titles of tabs | _string[]_ | `[]` |
|
||||||
| next-step-text `v4.0.8` | Text of next step button | _string_ | `''` |
|
| title | Toolbar title | _string_ | `''` |
|
||||||
| confirm-button-text | Text of confirm button | _string_ | `Confirm` |
|
| next-step-text `v4.0.8` | Text of next step button | _string_ | `''` |
|
||||||
| cancel-button-text | Text of cancel button | _string_ | `Cancel` |
|
| confirm-button-text | Text of confirm button | _string_ | `Confirm` |
|
||||||
|
| cancel-button-text | Text of cancel button | _string_ | `Cancel` |
|
||||||
|
|
||||||
### Slots
|
### Slots
|
||||||
|
|
||||||
@ -235,5 +314,15 @@ export default {
|
|||||||
The component exports the following type definitions:
|
The component exports the following type definitions:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import type { DatePickerProps, DatePickerColumnType } from 'vant';
|
import type { PickerGroupProps, PickerGroupThemeVars } from 'vant';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Theming
|
||||||
|
|
||||||
|
### CSS Variables
|
||||||
|
|
||||||
|
The component provides the following CSS variables, which can be used to customize styles. Please refer to [ConfigProvider component](#/en-US/config-provider).
|
||||||
|
|
||||||
|
| Name | Default Value | Description |
|
||||||
|
| ----------------------------- | -------------------- | ----------- |
|
||||||
|
| --van-picker-group-background | _--van-background-2_ | - |
|
||||||
|
@ -56,11 +56,13 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
const currentDate = ref(['2022', '06', '01']);
|
const currentDate = ref(['2022', '06', '01']);
|
||||||
const currentTime = ref(['12', '00']);
|
const currentTime = ref(['12', '00']);
|
||||||
|
|
||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
showToast(
|
showToast(
|
||||||
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
showToast('cancel');
|
showToast('cancel');
|
||||||
};
|
};
|
||||||
@ -70,6 +72,8 @@ export default {
|
|||||||
maxDate: new Date(2025, 5, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentDate,
|
currentDate,
|
||||||
currentTime,
|
currentTime,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -104,11 +108,13 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
const currentDate = ref(['2022', '06', '01']);
|
const currentDate = ref(['2022', '06', '01']);
|
||||||
const currentTime = ref(['12', '00']);
|
const currentTime = ref(['12', '00']);
|
||||||
|
|
||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
showToast(
|
showToast(
|
||||||
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
showToast('cancel');
|
showToast('cancel');
|
||||||
};
|
};
|
||||||
@ -118,6 +124,8 @@ export default {
|
|||||||
maxDate: new Date(2025, 5, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
currentDate,
|
currentDate,
|
||||||
currentTime,
|
currentTime,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -155,6 +163,7 @@ export default {
|
|||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
showToast(`${startDate.value.join('/')} ${endDate.value.join('/')}`);
|
showToast(`${startDate.value.join('/')} ${endDate.value.join('/')}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
showToast('cancel');
|
showToast('cancel');
|
||||||
};
|
};
|
||||||
@ -164,6 +173,8 @@ export default {
|
|||||||
maxDate: new Date(2025, 5, 1),
|
maxDate: new Date(2025, 5, 1),
|
||||||
endDate,
|
endDate,
|
||||||
startDate,
|
startDate,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -197,6 +208,7 @@ export default {
|
|||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
showToast(`${startTime.value.join(':')} ${endTime.value.join(':')}`);
|
showToast(`${startTime.value.join(':')} ${endTime.value.join(':')}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
showToast('cancel');
|
showToast('cancel');
|
||||||
};
|
};
|
||||||
@ -204,6 +216,73 @@ export default {
|
|||||||
return {
|
return {
|
||||||
endTime,
|
endTime,
|
||||||
startTime,
|
startTime,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 受控模式
|
||||||
|
|
||||||
|
`PickerGroup` 中 `tab` 的切换支持非受控模式和受控模式:
|
||||||
|
|
||||||
|
- 当未绑定 `v-model:active-tab` 时,PickerGroup 组件 `tab` 的切换完全由组件自身控制。
|
||||||
|
- 当绑定 `v-model:active-tab` 时,PickerGroup 支持受控模式,此时组件 `tab` 的切换同时支持 `v-model:active-tab` 的值和组件本身控制。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-button type="primary" @click="setActiveTab">
|
||||||
|
点击切换 tab,当前为 {{ activeTab }}
|
||||||
|
</van-button>
|
||||||
|
<van-picker-group
|
||||||
|
v-model:active-tab="activeTab"
|
||||||
|
title="预约日期"
|
||||||
|
:tabs="['选择日期', '选择时间']"
|
||||||
|
@confirm="onConfirm"
|
||||||
|
@cancel="onCancel"
|
||||||
|
>
|
||||||
|
<van-date-picker
|
||||||
|
v-model="currentDate"
|
||||||
|
:min-date="minDate"
|
||||||
|
:max-date="maxDate"
|
||||||
|
/>
|
||||||
|
<van-time-picker v-model="currentTime" />
|
||||||
|
</van-picker-group>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { showToast } from 'vant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const activeTab = ref(0);
|
||||||
|
const currentDate = ref(['2022', '06', '01']);
|
||||||
|
const currentTime = ref(['12', '00']);
|
||||||
|
|
||||||
|
const setActiveTab = () => {
|
||||||
|
activeTab.value = activeTab.value ? 0 : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onConfirm = () => {
|
||||||
|
showToast(
|
||||||
|
`${currentDate.value.join('/')} ${currentTime.value.join(':')}`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
showToast('cancel');
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
minDate: new Date(2020, 0, 1),
|
||||||
|
maxDate: new Date(2025, 5, 1),
|
||||||
|
activeTab,
|
||||||
|
currentDate,
|
||||||
|
currentTime,
|
||||||
|
setActiveTab,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -213,13 +292,14 @@ export default {
|
|||||||
|
|
||||||
### Props
|
### Props
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 |
|
| 参数 | 说明 | 类型 | 默认值 |
|
||||||
| ----------------------- | ---------------- | ---------- | ------ |
|
| ----------------------- | ------------------ | ------------------ | ------ |
|
||||||
| tabs | 设置标签页的标题 | _string[]_ | `[]` |
|
| v-model:active-tab | 设置当前选中的标签 | _number \| string_ | `0` |
|
||||||
| title | 顶部栏标题 | _string_ | `''` |
|
| tabs | 设置标签页的标题 | _string[]_ | `[]` |
|
||||||
| next-step-text `v4.0.8` | 下一步按钮的文字 | _string_ | `''` |
|
| title | 顶部栏标题 | _string_ | `''` |
|
||||||
| confirm-button-text | 确认按钮的文字 | _string_ | `确认` |
|
| next-step-text `v4.0.8` | 下一步按钮的文字 | _string_ | `''` |
|
||||||
| cancel-button-text | 取消按钮的文字 | _string_ | `取消` |
|
| confirm-button-text | 确认按钮的文字 | _string_ | `确认` |
|
||||||
|
| cancel-button-text | 取消按钮的文字 | _string_ | `取消` |
|
||||||
|
|
||||||
### Slots
|
### Slots
|
||||||
|
|
||||||
@ -235,5 +315,15 @@ export default {
|
|||||||
组件导出以下类型定义:
|
组件导出以下类型定义:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import type { PickerGroupProps } from 'vant';
|
import type { PickerGroupProps, PickerGroupThemeVars } from 'vant';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 主题定制
|
||||||
|
|
||||||
|
### 样式变量
|
||||||
|
|
||||||
|
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 [ConfigProvider 组件](#/zh-CN/config-provider)。
|
||||||
|
|
||||||
|
| 名称 | 默认值 | 描述 |
|
||||||
|
| ----------------------------- | -------------------- | ---- |
|
||||||
|
| --van-picker-group-background | _--van-background-2_ | - |
|
||||||
|
60
packages/vant/src/picker-group/demo/ControlTab.vue
Normal file
60
packages/vant/src/picker-group/demo/ControlTab.vue
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useTranslate } from '../../../docs/site';
|
||||||
|
import VanPickerGroup from '..';
|
||||||
|
import VanButton from '../../button';
|
||||||
|
import VanTimePicker from '../../time-picker';
|
||||||
|
import VanDatePicker from '../../date-picker';
|
||||||
|
import { showToast } from '../../toast';
|
||||||
|
|
||||||
|
const t = useTranslate({
|
||||||
|
'zh-CN': {
|
||||||
|
date: '选择日期',
|
||||||
|
time: '选择时间',
|
||||||
|
title: '预约日期',
|
||||||
|
btnText: '点击切换 tab,当前为 ',
|
||||||
|
},
|
||||||
|
'en-US': {
|
||||||
|
date: 'Date',
|
||||||
|
time: 'Time',
|
||||||
|
title: 'Title',
|
||||||
|
btnText: 'toggle tab, current ',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const activeTab = ref(0);
|
||||||
|
const currentTime = ref(['12', '00']);
|
||||||
|
const currentDate = ref(['2022', '06', '01']);
|
||||||
|
const minDate = new Date(2020, 0, 1);
|
||||||
|
const maxDate = new Date(2025, 5, 1);
|
||||||
|
|
||||||
|
const onConfirm = () => {
|
||||||
|
showToast(`${currentDate.value.join('/')} ${currentTime.value.join(':')}`);
|
||||||
|
};
|
||||||
|
const onCancel = () => {
|
||||||
|
showToast('cancel');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setActiveTab = () => {
|
||||||
|
activeTab.value = activeTab.value ? 0 : 1;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<van-button style="margin: 10px 0" type="primary" @click="setActiveTab">
|
||||||
|
{{ t('btnText') + activeTab }}
|
||||||
|
</van-button>
|
||||||
|
<van-picker-group
|
||||||
|
v-model:active-tab="activeTab"
|
||||||
|
:title="t('title')"
|
||||||
|
:tabs="[t('date'), t('time')]"
|
||||||
|
@confirm="onConfirm"
|
||||||
|
@cancel="onCancel"
|
||||||
|
>
|
||||||
|
<van-date-picker
|
||||||
|
v-model="currentDate"
|
||||||
|
:min-date="minDate"
|
||||||
|
:max-date="maxDate"
|
||||||
|
/>
|
||||||
|
<van-time-picker v-model="currentTime" />
|
||||||
|
</van-picker-group>
|
||||||
|
</template>
|
@ -3,6 +3,7 @@ import SelectDateTime from './SelectDateTime.vue';
|
|||||||
import SelectTimeRange from './SelectTimeRange.vue';
|
import SelectTimeRange from './SelectTimeRange.vue';
|
||||||
import SelectDateRange from './SelectDateRange.vue';
|
import SelectDateRange from './SelectDateRange.vue';
|
||||||
import NextStepButton from './NextStepButton.vue';
|
import NextStepButton from './NextStepButton.vue';
|
||||||
|
import ControlTab from './ControlTab.vue';
|
||||||
import { useTranslate } from '../../../docs/site';
|
import { useTranslate } from '../../../docs/site';
|
||||||
|
|
||||||
const t = useTranslate({
|
const t = useTranslate({
|
||||||
@ -11,12 +12,14 @@ const t = useTranslate({
|
|||||||
selectDateRange: '选择日期范围',
|
selectDateRange: '选择日期范围',
|
||||||
selectTimeRange: '选择时间范围',
|
selectTimeRange: '选择时间范围',
|
||||||
nextStepButton: '下一步按钮',
|
nextStepButton: '下一步按钮',
|
||||||
|
controlled: '受控模式',
|
||||||
},
|
},
|
||||||
'en-US': {
|
'en-US': {
|
||||||
selectDateTime: 'Select Date Time',
|
selectDateTime: 'Select Date Time',
|
||||||
selectDateRange: 'Select Date Range',
|
selectDateRange: 'Select Date Range',
|
||||||
selectTimeRange: 'Select Time Range',
|
selectTimeRange: 'Select Time Range',
|
||||||
nextStepButton: 'Next Step Button',
|
nextStepButton: 'Next Step Button',
|
||||||
|
controlled: 'Controlled Mode',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -37,4 +40,8 @@ const t = useTranslate({
|
|||||||
<demo-block card :title="t('selectTimeRange')">
|
<demo-block card :title="t('selectTimeRange')">
|
||||||
<select-time-range />
|
<select-time-range />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block card :title="t('controlled')">
|
||||||
|
<control-tab />
|
||||||
|
</demo-block>
|
||||||
</template>
|
</template>
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { mount } from '../../../test';
|
import { later, mount } from '../../../test';
|
||||||
import { Picker, PickerConfirmEventParams } from '../../picker';
|
import { Picker, PickerConfirmEventParams } from '../../picker';
|
||||||
import { PickerGroup } from '..';
|
import { PickerGroup } from '..';
|
||||||
|
|
||||||
@ -108,3 +108,38 @@ test('should switch to next step when click confirm button', async () => {
|
|||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('support controlled mode to set active-tab', async () => {
|
||||||
|
const value1 = ref(['1']);
|
||||||
|
const value2 = ref(['2']);
|
||||||
|
const activeTab = ref(0);
|
||||||
|
|
||||||
|
const wrapper = mount({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<PickerGroup
|
||||||
|
activeTab={activeTab.value}
|
||||||
|
title="Title"
|
||||||
|
tabs={['Tab1', 'Tab2']}
|
||||||
|
>
|
||||||
|
<Picker
|
||||||
|
v-model={value1.value}
|
||||||
|
columns={[{ text: '1', value: '1' }]}
|
||||||
|
/>
|
||||||
|
<Picker
|
||||||
|
v-model={value2.value}
|
||||||
|
columns={[{ text: '2', value: '2' }]}
|
||||||
|
/>
|
||||||
|
</PickerGroup>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await later();
|
||||||
|
const tabs = wrapper.findAll('.van-tab');
|
||||||
|
expect(tabs[0]?.classes()).toContain('van-tab--active');
|
||||||
|
|
||||||
|
activeTab.value = 1;
|
||||||
|
await later();
|
||||||
|
expect(tabs[1]?.classes()).toContain('van-tab--active');
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user