mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-04 21:32:44 +08:00
feat: add new PickerGroup component (#11005)
* feat: add PickerGroup component * chore: remove log * chore: en doc * chore: add snapshot * docs: update
This commit is contained in:
parent
a677bee2b8
commit
1afe960f30
67
packages/vant/src/picker-group/PickerGroup.tsx
Normal file
67
packages/vant/src/picker-group/PickerGroup.tsx
Normal file
@ -0,0 +1,67 @@
|
||||
import { defineComponent, type InjectionKey, type ExtractPropTypes } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { extend, makeArrayProp, createNamespace } from '../utils';
|
||||
|
||||
// Composables
|
||||
import { useChildren } from '@vant/use';
|
||||
|
||||
// Components
|
||||
import { Tab } from '../tab';
|
||||
import { Tabs } from '../tabs';
|
||||
import Toolbar, { pickerToolbarProps } from '../picker/PickerToolbar';
|
||||
|
||||
const [name, bem] = createNamespace('picker-group');
|
||||
|
||||
export type PickerGroupProvide = Record<string, string>;
|
||||
|
||||
export const PICKER_GROUP_KEY: InjectionKey<PickerGroupProvide> = Symbol(name);
|
||||
|
||||
export const pickerGroupProps = extend(
|
||||
{
|
||||
tabs: makeArrayProp<string>(),
|
||||
},
|
||||
pickerToolbarProps
|
||||
);
|
||||
|
||||
export type PickerGroupProps = ExtractPropTypes<typeof pickerGroupProps>;
|
||||
|
||||
export default defineComponent({
|
||||
name,
|
||||
|
||||
props: pickerGroupProps,
|
||||
|
||||
emits: ['confirm', 'cancel'],
|
||||
|
||||
setup(props, { emit, slots }) {
|
||||
const { children, linkChildren } = useChildren(PICKER_GROUP_KEY);
|
||||
|
||||
linkChildren();
|
||||
|
||||
const onConfirm = () => {
|
||||
emit(
|
||||
'confirm',
|
||||
children.map((item) => item.confirm())
|
||||
);
|
||||
};
|
||||
|
||||
const onCancel = () => emit('cancel');
|
||||
|
||||
return () => {
|
||||
const childNodes = slots.default?.();
|
||||
|
||||
return (
|
||||
<div class={bem()}>
|
||||
<Toolbar {...props} onConfirm={onConfirm} onCancel={onCancel} />
|
||||
<Tabs shrink class={bem('tabs')} animated>
|
||||
{props.tabs.map((title, index) => (
|
||||
<Tab title={title} titleClass={bem('tab-title')}>
|
||||
{childNodes?.[index]}
|
||||
</Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
185
packages/vant/src/picker-group/README.md
Normal file
185
packages/vant/src/picker-group/README.md
Normal file
@ -0,0 +1,185 @@
|
||||
# PickerGroup
|
||||
|
||||
### Intro
|
||||
|
||||
Used to combine multiple Picker components, allow users to select multiple value.
|
||||
|
||||
The following components can be placed inside PickerGroup:
|
||||
|
||||
- [Picker](#/en-US/picker)
|
||||
- [Area](#/en-US/area)
|
||||
- [DatePicker](#/en-US/date-picker)
|
||||
- [TimePicker](#/en-US/time-picker)
|
||||
- Other custom components based on Picker component
|
||||
|
||||
### Install
|
||||
|
||||
Register component globally via `app.use`, refer to [Component Registration](#/en-US/advanced-usage#zu-jian-zhu-ce) for more registration ways.
|
||||
|
||||
```js
|
||||
import { createApp } from 'vue';
|
||||
import { PickerGroup } from 'vant';
|
||||
|
||||
const app = createApp();
|
||||
app.use(PickerGroup);
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Select Date Time
|
||||
|
||||
Place a `DatePicker` component and a `TimePicker` component in the default slot of the `PickerGroup` to select both a date and a time.
|
||||
|
||||
`PickerGroup` will render a unified toolbar, so the child components will not render is's toolbar, and the toolbar props and events need to be set to the `PickerGroup`, such as the `title` prop, `confirm` event, `cancel` event, etc. Other props and events in child components can be used as before.
|
||||
|
||||
```html
|
||||
<van-picker-group
|
||||
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 currentDate = ref(['2022', '06', '01']);
|
||||
const currentTime = ref(['12', '00']);
|
||||
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),
|
||||
currentDate,
|
||||
currentTime,
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Select Date Range
|
||||
|
||||
Place two `DatePicker` components in the default slot of `PickerGroup` to select the time range.
|
||||
|
||||
```html
|
||||
<van-picker-group
|
||||
title="Title"
|
||||
:tabs="['Start Date', 'End Date']"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
>
|
||||
<van-date-picker v-model="startEnd" :min-date="minDate" :max-date="maxDate" />
|
||||
<van-date-picker v-model="endDate" :min-date="minDate" :max-date="maxDate" />
|
||||
</van-picker-group>
|
||||
```
|
||||
|
||||
```js
|
||||
import { ref } from 'vue';
|
||||
import { showToast } from 'vant';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const startDate = ref(['2022', '06', '01']);
|
||||
const endDate = ref(['2023', '06', '01']);
|
||||
|
||||
const onConfirm = () => {
|
||||
showToast(`${startDate.value.join('/')} ${endDate.value.join('/')}`);
|
||||
};
|
||||
const onCancel = () => {
|
||||
showToast('cancel');
|
||||
};
|
||||
|
||||
return {
|
||||
minDate: new Date(2020, 0, 1),
|
||||
maxDate: new Date(2025, 5, 1),
|
||||
endDate,
|
||||
startDate,
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Select Time Range
|
||||
|
||||
Place two `TimePicker` components in the default slot of `PickerGroup` to select the time range.
|
||||
|
||||
```html
|
||||
<van-picker-group
|
||||
title="Title"
|
||||
:tabs="['Start Time', 'End Time']"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
>
|
||||
<van-time-picker v-model="startEnd" />
|
||||
<van-time-picker v-model="endDate" />
|
||||
</van-picker-group>
|
||||
```
|
||||
|
||||
```js
|
||||
import { ref } from 'vue';
|
||||
import { showToast } from 'vant';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const startTime = ref(['12', '00']);
|
||||
const endTime = ref(['12', '00']);
|
||||
|
||||
const onConfirm = () => {
|
||||
showToast(`${startTime.value.join(':')} ${endTime.value.join(':')}`);
|
||||
};
|
||||
const onCancel = () => {
|
||||
showToast('cancel');
|
||||
};
|
||||
|
||||
return {
|
||||
endTime,
|
||||
startTime,
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
| ------------------- | ---------------------- | -------- | --------- |
|
||||
| title | Toolbar title | _string_ | `''` |
|
||||
| confirm-button-text | Text of confirm button | _string_ | `Confirm` |
|
||||
| cancel-button-text | Text of cancel button | _string_ | `Cancel` |
|
||||
|
||||
### Slots
|
||||
|
||||
| Name | Description | SlotProps |
|
||||
| ------- | -------------------------- | --------- |
|
||||
| toolbar | Custom toolbar content | - |
|
||||
| title | Custom title | - |
|
||||
| confirm | Custom confirm button text | - |
|
||||
| cancel | Custom cancel button text | - |
|
||||
|
||||
### Types
|
||||
|
||||
The component exports the following type definitions:
|
||||
|
||||
```ts
|
||||
import type { DatePickerProps, DatePickerColumnType } from 'vant';
|
||||
```
|
185
packages/vant/src/picker-group/README.zh-CN.md
Normal file
185
packages/vant/src/picker-group/README.zh-CN.md
Normal file
@ -0,0 +1,185 @@
|
||||
# PickerGroup 选择器组
|
||||
|
||||
### 介绍
|
||||
|
||||
用于结合多个 Picker 选择器组件,在一次交互中完成多个值的选择。
|
||||
|
||||
PickerGroup 中可以放置以下组件:
|
||||
|
||||
- [Picker](#/zh-CN/picker)
|
||||
- [Area](#/zh-CN/area)
|
||||
- [DatePicker](#/zh-CN/date-picker)
|
||||
- [TimePicker](<(#/zh-CN/time-picker)>)
|
||||
- 其他基于 Picker 封装的自定义组件
|
||||
|
||||
### 引入
|
||||
|
||||
通过以下方式来全局注册组件,更多注册方式请参考[组件注册](#/zh-CN/advanced-usage#zu-jian-zhu-ce)。
|
||||
|
||||
```js
|
||||
import { createApp } from 'vue';
|
||||
import { PickerGroup } from 'vant';
|
||||
|
||||
const app = createApp();
|
||||
app.use(PickerGroup);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 选择日期时间
|
||||
|
||||
在 `PickerGroup` 的默认插槽中放置一个 `DatePicker` 组件和一个 `TimePicker` 组件,可以实现同时选择日期和时间的交互效果。
|
||||
|
||||
`PickerGroup` 会代替子组件来渲染统一的标题栏,这意味着子组件不会渲染单独的标题栏,与标题栏有关的 props 和 events 需要设置到 `PickerGroup` 上,比如 `title` 属性、`confirm` 事件、`cancel` 事件等,而子组件中与标题栏无关的属性和事件可以正常使用。
|
||||
|
||||
```html
|
||||
<van-picker-group
|
||||
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 currentDate = ref(['2022', '06', '01']);
|
||||
const currentTime = ref(['12', '00']);
|
||||
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),
|
||||
currentDate,
|
||||
currentTime,
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 选择日期范围
|
||||
|
||||
在 `PickerGroup` 的默认插槽中放置两个 `DatePicker` 组件,可以实现选择日期范围的交互效果。
|
||||
|
||||
```html
|
||||
<van-picker-group
|
||||
title="预约日期"
|
||||
:tabs="['开始日期', '结束日期']"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
>
|
||||
<van-date-picker v-model="startEnd" :min-date="minDate" :max-date="maxDate" />
|
||||
<van-date-picker v-model="endDate" :min-date="minDate" :max-date="maxDate" />
|
||||
</van-picker-group>
|
||||
```
|
||||
|
||||
```js
|
||||
import { ref } from 'vue';
|
||||
import { showToast } from 'vant';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const startDate = ref(['2022', '06', '01']);
|
||||
const endDate = ref(['2023', '06', '01']);
|
||||
|
||||
const onConfirm = () => {
|
||||
showToast(`${startDate.value.join('/')} ${endDate.value.join('/')}`);
|
||||
};
|
||||
const onCancel = () => {
|
||||
showToast('cancel');
|
||||
};
|
||||
|
||||
return {
|
||||
minDate: new Date(2020, 0, 1),
|
||||
maxDate: new Date(2025, 5, 1),
|
||||
endDate,
|
||||
startDate,
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 选择时间范围
|
||||
|
||||
在 `PickerGroup` 的默认插槽中放置两个 `TimePicker` 组件,可以实现选择时间范围的交互效果。
|
||||
|
||||
```html
|
||||
<van-picker-group
|
||||
title="预约时间"
|
||||
:tabs="['开始时间', '结束时间']"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
>
|
||||
<van-time-picker v-model="startEnd" />
|
||||
<van-time-picker v-model="endDate" />
|
||||
</van-picker-group>
|
||||
```
|
||||
|
||||
```js
|
||||
import { ref } from 'vue';
|
||||
import { showToast } from 'vant';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const startTime = ref(['12', '00']);
|
||||
const endTime = ref(['12', '00']);
|
||||
|
||||
const onConfirm = () => {
|
||||
showToast(`${startTime.value.join(':')} ${endTime.value.join(':')}`);
|
||||
};
|
||||
const onCancel = () => {
|
||||
showToast('cancel');
|
||||
};
|
||||
|
||||
return {
|
||||
endTime,
|
||||
startTime,
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ------------------- | ------------ | -------- | ------ |
|
||||
| title | 顶部栏标题 | _string_ | `''` |
|
||||
| confirm-button-text | 确认按钮文字 | _string_ | `确认` |
|
||||
| cancel-button-text | 取消按钮文字 | _string_ | `取消` |
|
||||
|
||||
### Slots
|
||||
|
||||
| 名称 | 说明 | 参数 |
|
||||
| ------- | ---------------------- | ---- |
|
||||
| toolbar | 自定义整个顶部栏的内容 | - |
|
||||
| title | 自定义标题内容 | - |
|
||||
| confirm | 自定义确认按钮内容 | - |
|
||||
| cancel | 自定义取消按钮内容 | - |
|
||||
|
||||
### 类型定义
|
||||
|
||||
组件导出以下类型定义:
|
||||
|
||||
```ts
|
||||
import type { PickerGroupProps } from 'vant';
|
||||
```
|
60
packages/vant/src/picker-group/demo/SelectDateRange.vue
Normal file
60
packages/vant/src/picker-group/demo/SelectDateRange.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import { useTranslate } from '../../../docs/site';
|
||||
import VanPickerGroup from '..';
|
||||
import VanDatePicker from '../../date-picker';
|
||||
import { showToast } from '../../toast';
|
||||
|
||||
const t = useTranslate({
|
||||
'zh-CN': {
|
||||
startDate: '开始日期',
|
||||
endDate: '结束日期',
|
||||
title: '预约日期',
|
||||
},
|
||||
'en-US': {
|
||||
startDate: 'Start Date',
|
||||
endDate: 'End Date',
|
||||
title: 'Title',
|
||||
},
|
||||
});
|
||||
|
||||
const startDate = ref(['2022', '06', '01']);
|
||||
const endDate = ref(['2023', '06', '01']);
|
||||
const minDate = new Date(2020, 0, 1);
|
||||
const maxDate = new Date(2025, 5, 1);
|
||||
const endMinDate = computed(
|
||||
() =>
|
||||
new Date(
|
||||
Number(startDate.value[0]),
|
||||
Number(startDate.value[1]) - 1,
|
||||
Number(startDate.value[2])
|
||||
)
|
||||
);
|
||||
|
||||
const onConfirm = () => {
|
||||
showToast(`${startDate.value.join('/')} - ${endDate.value.join('/')}`);
|
||||
};
|
||||
const onCancel = () => {
|
||||
showToast('cancel');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-picker-group
|
||||
:title="t('title')"
|
||||
:tabs="[t('startDate'), t('endDate')]"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
>
|
||||
<van-date-picker
|
||||
v-model="startDate"
|
||||
:min-date="minDate"
|
||||
:max-date="maxDate"
|
||||
/>
|
||||
<van-date-picker
|
||||
v-model="endDate"
|
||||
:min-date="endMinDate"
|
||||
:max-date="maxDate"
|
||||
/>
|
||||
</van-picker-group>
|
||||
</template>
|
49
packages/vant/src/picker-group/demo/SelectDateTime.vue
Normal file
49
packages/vant/src/picker-group/demo/SelectDateTime.vue
Normal file
@ -0,0 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useTranslate } from '../../../docs/site';
|
||||
import VanPickerGroup from '..';
|
||||
import VanTimePicker from '../../time-picker';
|
||||
import VanDatePicker from '../../date-picker';
|
||||
import { showToast } from '../../toast';
|
||||
|
||||
const t = useTranslate({
|
||||
'zh-CN': {
|
||||
date: '选择日期',
|
||||
time: '选择时间',
|
||||
title: '预约日期',
|
||||
},
|
||||
'en-US': {
|
||||
date: 'Date',
|
||||
time: 'Time',
|
||||
title: 'Title',
|
||||
},
|
||||
});
|
||||
|
||||
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');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-picker-group
|
||||
: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>
|
42
packages/vant/src/picker-group/demo/SelectTimeRange.vue
Normal file
42
packages/vant/src/picker-group/demo/SelectTimeRange.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useTranslate } from '../../../docs/site';
|
||||
import VanPickerGroup from '..';
|
||||
import VanTimePicker from '../../time-picker';
|
||||
import { showToast } from '../../toast';
|
||||
|
||||
const t = useTranslate({
|
||||
'zh-CN': {
|
||||
startTime: '开始时间',
|
||||
endTime: '结束时间',
|
||||
title: '预约时间',
|
||||
},
|
||||
'en-US': {
|
||||
startTime: 'Start Time',
|
||||
endTime: 'End Time',
|
||||
title: 'Title',
|
||||
},
|
||||
});
|
||||
|
||||
const startTime = ref(['12', '00']);
|
||||
const endTime = ref(['13', '00']);
|
||||
|
||||
const onConfirm = () => {
|
||||
showToast(`${startTime.value.join(':')} - ${endTime.value.join(':')}`);
|
||||
};
|
||||
const onCancel = () => {
|
||||
showToast('cancel');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-picker-group
|
||||
:title="t('title')"
|
||||
:tabs="[t('startTime'), t('endTime')]"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onCancel"
|
||||
>
|
||||
<van-time-picker v-model="startTime" />
|
||||
<van-time-picker v-model="endTime" />
|
||||
</van-picker-group>
|
||||
</template>
|
33
packages/vant/src/picker-group/demo/index.vue
Normal file
33
packages/vant/src/picker-group/demo/index.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import SelectDateTime from './SelectDateTime.vue';
|
||||
import SelectTimeRange from './SelectTimeRange.vue';
|
||||
import SelectDateRange from './SelectDateRange.vue';
|
||||
import { useTranslate } from '../../../docs/site';
|
||||
|
||||
const t = useTranslate({
|
||||
'zh-CN': {
|
||||
selectDateTime: '选择日期时间',
|
||||
selectDateRange: '选择日期范围',
|
||||
selectTimeRange: '选择时间范围',
|
||||
},
|
||||
'en-US': {
|
||||
selectDateTime: 'Select Date Time',
|
||||
selectDateRange: 'Select Date Range',
|
||||
selectTimeRange: 'Select Time Range',
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<demo-block card :title="t('selectDateTime')">
|
||||
<select-date-time />
|
||||
</demo-block>
|
||||
|
||||
<demo-block card :title="t('selectDateRange')">
|
||||
<select-date-range />
|
||||
</demo-block>
|
||||
|
||||
<demo-block card :title="t('selectTimeRange')">
|
||||
<select-time-range />
|
||||
</demo-block>
|
||||
</template>
|
15
packages/vant/src/picker-group/index.less
Normal file
15
packages/vant/src/picker-group/index.less
Normal file
@ -0,0 +1,15 @@
|
||||
body {
|
||||
--van-picker-group-background: var(--van-background-2);
|
||||
}
|
||||
|
||||
.van-picker-group {
|
||||
background: var(--van-picker-group-background);
|
||||
|
||||
&__tabs {
|
||||
margin-top: var(--van-padding-base);
|
||||
}
|
||||
|
||||
&__tab-title {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
12
packages/vant/src/picker-group/index.ts
Normal file
12
packages/vant/src/picker-group/index.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { withInstall } from '../utils';
|
||||
import _PickerGroup, { PickerGroupProps } from './PickerGroup';
|
||||
|
||||
export const PickerGroup = withInstall(_PickerGroup);
|
||||
export default PickerGroup;
|
||||
export type { PickerGroupProps };
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanPickerGroup: typeof PickerGroup;
|
||||
}
|
||||
}
|
3976
packages/vant/src/picker-group/test/__snapshots__/demo.spec.ts.snap
Normal file
3976
packages/vant/src/picker-group/test/__snapshots__/demo.spec.ts.snap
Normal file
File diff suppressed because it is too large
Load Diff
4
packages/vant/src/picker-group/test/demo.spec.ts
Normal file
4
packages/vant/src/picker-group/test/demo.spec.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import Demo from '../demo/index.vue';
|
||||
import { snapshotDemo } from '../../../test/demo';
|
||||
|
||||
snapshotDemo(Demo);
|
@ -33,7 +33,7 @@ import {
|
||||
} from './utils';
|
||||
|
||||
// Composables
|
||||
import { useChildren, useEventListener } from '@vant/use';
|
||||
import { useChildren, useEventListener, useParent } from '@vant/use';
|
||||
import { useExpose } from '../composables/use-expose';
|
||||
|
||||
// Components
|
||||
@ -53,6 +53,7 @@ import type {
|
||||
PickerFieldNames,
|
||||
PickerToolbarPosition,
|
||||
} from './types';
|
||||
import { PICKER_GROUP_KEY } from '../picker-group/PickerGroup';
|
||||
|
||||
export const pickerSharedProps = extend(
|
||||
{
|
||||
@ -85,7 +86,9 @@ export default defineComponent({
|
||||
|
||||
setup(props, { emit, slots }) {
|
||||
const columnsRef = ref<HTMLElement>();
|
||||
const selectedValues = ref(props.modelValue);
|
||||
const selectedValues = ref(props.modelValue.slice(0));
|
||||
|
||||
const { parent } = useParent(PICKER_GROUP_KEY);
|
||||
const { children, linkChildren } = useChildren(PICKER_KEY);
|
||||
|
||||
linkChildren();
|
||||
@ -127,7 +130,7 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
const getEventParams = () => ({
|
||||
selectedValues: selectedValues.value,
|
||||
selectedValues: selectedValues.value.slice(0),
|
||||
selectedOptions: selectedOptions.value,
|
||||
});
|
||||
|
||||
@ -158,7 +161,9 @@ export default defineComponent({
|
||||
|
||||
const confirm = () => {
|
||||
children.forEach((child) => child.stopMomentum());
|
||||
emit('confirm', getEventParams());
|
||||
const params = getEventParams();
|
||||
emit('confirm', params);
|
||||
return params;
|
||||
};
|
||||
|
||||
const cancel = () => emit('cancel', getEventParams());
|
||||
@ -210,7 +215,7 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
const renderToolbar = () => {
|
||||
if (props.showToolbar) {
|
||||
if (props.showToolbar && !parent) {
|
||||
return (
|
||||
<Toolbar
|
||||
v-slots={pick(slots, pickerToolbarSlots)}
|
||||
@ -244,7 +249,7 @@ export default defineComponent({
|
||||
() => props.modelValue,
|
||||
(newValues) => {
|
||||
if (!isSameValue(newValues, selectedValues.value)) {
|
||||
selectedValues.value = newValues;
|
||||
selectedValues.value = newValues.slice(0);
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
@ -253,7 +258,7 @@ export default defineComponent({
|
||||
selectedValues,
|
||||
(newValues) => {
|
||||
if (!isSameValue(newValues, props.modelValue)) {
|
||||
emit('update:modelValue', newValues);
|
||||
emit('update:modelValue', newValues.slice(0));
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
|
@ -186,6 +186,10 @@ export default {
|
||||
path: 'picker',
|
||||
title: 'Picker 选择器',
|
||||
},
|
||||
{
|
||||
path: 'picker-group',
|
||||
title: 'PickerGroup 选择器组',
|
||||
},
|
||||
{
|
||||
path: 'radio',
|
||||
title: 'Radio 单选框',
|
||||
@ -593,6 +597,10 @@ export default {
|
||||
path: 'picker',
|
||||
title: 'Picker',
|
||||
},
|
||||
{
|
||||
path: 'picker-group',
|
||||
title: 'PickerGroup',
|
||||
},
|
||||
{
|
||||
path: 'radio',
|
||||
title: 'Radio',
|
||||
|
Loading…
x
Reference in New Issue
Block a user