+
+ -
+
+ 00
+
+
+ -
+
+ 10
+
+
+ -
+
+ 20
+
+
+ -
+
+ 30
+
+
+ -
+
+ 40
+
+
+ -
+
+ 50
diff --git a/packages/vant/src/time-picker/test/__snapshots__/index.spec.tsx.snap b/packages/vant/src/time-picker/test/__snapshots__/index.spec.tsx.snap
new file mode 100644
index 000000000..95f3484ed
--- /dev/null
+++ b/packages/vant/src/time-picker/test/__snapshots__/index.spec.tsx.snap
@@ -0,0 +1,191 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should filter options when using filter prop 1`] = `
+
+
+
+
+
+
+
+
+ -
+
+ 00
+
+
+ -
+
+ 10
+
+
+ -
+
+ 20
+
+
+
+
+
+
+ -
+
+ 00
+
+
+ -
+
+ 20
+
+
+ -
+
+ 40
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`should format options correctly when using formatter prop 1`] = `
+
+
+
+
+
+
+
+
+ -
+
+ 00 hour
+
+
+ -
+
+ 10 hour
+
+
+ -
+
+ 20 hour
+
+
+
+
+
+
+ -
+
+ 00 minute
+
+
+ -
+
+ 20 minute
+
+
+ -
+
+ 40 minute
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/packages/vant/src/time-picker/test/demo.spec.ts b/packages/vant/src/time-picker/test/demo.spec.ts
new file mode 100644
index 000000000..c0e0c95b9
--- /dev/null
+++ b/packages/vant/src/time-picker/test/demo.spec.ts
@@ -0,0 +1,4 @@
+import Demo from '../demo/index.vue';
+import { snapshotDemo } from '../../../test/demo';
+
+snapshotDemo(Demo);
diff --git a/packages/vant/src/time-picker/test/index.spec.tsx b/packages/vant/src/time-picker/test/index.spec.tsx
new file mode 100644
index 000000000..2435b1ef1
--- /dev/null
+++ b/packages/vant/src/time-picker/test/index.spec.tsx
@@ -0,0 +1,173 @@
+import TimePicker from '../TimePicker';
+import { mount } from '../../../test';
+import type { PickerOption } from '../../picker';
+
+function filter(type: string, options: PickerOption[]): PickerOption[] {
+ const mod = type === 'minute' ? 20 : 10;
+ return options.filter((option) => Number(option.value) % mod === 0);
+}
+
+test('should format initial value correctly', () => {
+ const onUpdate = jest.fn();
+ mount(TimePicker, {
+ props: {
+ minHour: 22,
+ minMinute: 58,
+ 'onUpdate:modelValue': onUpdate,
+ },
+ });
+
+ expect(onUpdate.mock.calls[0]).toEqual([['22', '58']]);
+});
+
+test('should update modelValue correctly when using max-hour and max-minute prop', () => {
+ const onUpdate = jest.fn();
+ mount(TimePicker, {
+ props: {
+ modelValue: ['23', '59'],
+ maxHour: 2,
+ maxMinute: 2,
+ 'onUpdate:modelValue': onUpdate,
+ },
+ });
+
+ expect(onUpdate.mock.calls[0]).toEqual([['00', '00']]);
+});
+
+test('should filter options when using filter prop', () => {
+ const wrapper = mount(TimePicker, {
+ props: {
+ filter,
+ modelValue: ['12', '00'],
+ },
+ });
+
+ expect(wrapper.html()).toMatchSnapshot();
+});
+
+test('should format options correctly when using formatter prop', async () => {
+ const formatter = (type: string, option: PickerOption): PickerOption => {
+ option.text = `${option.text} ${type}`;
+ return option;
+ };
+ const wrapper = mount(TimePicker, {
+ props: {
+ filter,
+ formatter,
+ modelValue: ['12', '00'],
+ },
+ });
+
+ expect(wrapper.html()).toMatchSnapshot();
+});
+
+test('should emit confirm event after clicking the confirm button', () => {
+ const wrapper = mount(TimePicker, {
+ props: {
+ modelValue: ['12', '00'],
+ },
+ });
+
+ wrapper.find('.van-picker__confirm').trigger('click');
+ expect(wrapper.emitted('confirm')).toEqual([
+ [
+ {
+ selectedOptions: [
+ { text: '12', value: '12' },
+ { text: '00', value: '00' },
+ ],
+ selectedValues: ['12', '00'],
+ },
+ ],
+ ]);
+});
+
+test('should emit cancel event after clicking the cancel button', () => {
+ const wrapper = mount(TimePicker);
+
+ wrapper.find('.van-picker__cancel').trigger('click');
+ expect(wrapper.emitted('cancel')).toBeTruthy();
+});
+
+test('should emit confirm event correctly after setting values', async () => {
+ const wrapper = mount(TimePicker);
+
+ await wrapper.setProps({ modelValue: ['00', '00'] });
+ await wrapper.find('.van-picker__confirm').trigger('click');
+ await wrapper.setProps({ modelValue: ['22', '30'] });
+ await wrapper.find('.van-picker__confirm').trigger('click');
+
+ expect(wrapper.emitted('confirm')).toEqual([
+ [
+ {
+ selectedOptions: [
+ { text: '00', value: '00' },
+ { text: '00', value: '00' },
+ ],
+ selectedValues: ['00', '00'],
+ },
+ ],
+ [
+ {
+ selectedOptions: [
+ { text: '22', value: '22' },
+ { text: '30', value: '30' },
+ ],
+ selectedValues: ['22', '30'],
+ },
+ ],
+ ]);
+});
+
+test('should emit confirm event correctly after setting range', async () => {
+ const onUpdate = jest.fn();
+ const wrapper = mount(TimePicker, {
+ props: {
+ minHour: 0,
+ minMinute: 0,
+ modelValue: ['12', '00'],
+ 'onUpdate:modelValue': onUpdate,
+ },
+ });
+
+ await wrapper.setProps({ minHour: 20, minMinute: 30 });
+ await wrapper.find('.van-picker__confirm').trigger('click');
+ expect(onUpdate.mock.calls[0]).toEqual([['20', '30']]);
+ expect(wrapper.emitted('confirm')).toEqual([
+ [
+ {
+ selectedOptions: [
+ { text: '20', value: '20' },
+ { text: '30', value: '30' },
+ ],
+ selectedValues: ['20', '30'],
+ },
+ ],
+ ]);
+});
+
+test('should emit confirm event correctly after setting smaller max-hour and max-minute', async () => {
+ const wrapper = mount(TimePicker, {
+ props: {
+ modelValue: ['23', '59'],
+ },
+ });
+
+ await wrapper.setProps({
+ maxHour: 2,
+ maxMinute: 2,
+ });
+
+ await wrapper.find('.van-picker__confirm').trigger('click');
+ expect(wrapper.emitted('confirm')).toEqual([
+ [
+ {
+ selectedOptions: [
+ { text: '00', value: '00' },
+ { text: '00', value: '00' },
+ ],
+ selectedValues: ['00', '00'],
+ },
+ ],
+ ]);
+});
diff --git a/packages/vant/src/toast/README.md b/packages/vant/src/toast/README.md
index 712750ca0..d65983e51 100644
--- a/packages/vant/src/toast/README.md
+++ b/packages/vant/src/toast/README.md
@@ -16,18 +16,34 @@ const app = createApp();
app.use(Toast);
```
+### Function Call
+
+Vant provides some utility functions that can quickly evoke global `Toast` components.
+
+For example, calling the `showToast` function will render a Toast directly in the page.
+
+```js
+import { showToast } from 'vant';
+
+showToast('Some messages');
+```
+
## Usage
### Text
```js
-Toast('Some messages');
+import { showToast } from 'vant';
+
+showToast('Some messages');
```
### Loading
```js
-Toast.loading({
+import { showLoadingToast } from 'vant';
+
+showLoadingToast({
message: 'Loading...',
forbidClick: true,
});
@@ -36,24 +52,28 @@ Toast.loading({
### Success/Fail
```js
-Toast.success('Success');
-Toast.fail('Fail');
+import { showSuccessToast, showFailToast } from 'vant';
+
+showSuccessToast('Success');
+showFailToast('Fail');
```
### Custom Icon
```js
-Toast({
+import { showToast, showLoadingToast } from 'vant';
+
+showToast({
message: 'Custom Icon',
icon: 'like-o',
});
-Toast({
+showToast({
message: 'Custom Image',
icon: 'https://fastly.jsdelivr.net/npm/@vant/assets/logo.png',
});
-Toast.loading({
+showLoadingToast({
message: 'Loading...',
forbidClick: true,
loadingType: 'spinner',
@@ -63,12 +83,14 @@ Toast.loading({
### Custom Position
```js
-Toast({
+import { showToast } from 'vant';
+
+showToast({
message: 'Top',
position: 'top',
});
-Toast({
+showToast({
message: 'Bottom',
position: 'bottom',
});
@@ -77,7 +99,9 @@ Toast({
### Update Message
```js
-const toast = Toast.loading({
+import { showLoadingToast, closeToast } from 'vant';
+
+const toast = showLoadingToast({
duration: 0,
forbidClick: true,
loadingType: 'spinner',
@@ -91,67 +115,84 @@ const timer = setInterval(() => {
toast.message = `${second} seconds`;
} else {
clearInterval(timer);
- Toast.clear();
+ closeToast();
}
}, 1000);
```
-### Global Method
-
-After registering the Toast component through `app.use`, the `$toast` method will be automatically mounted on all subcomponents of the app.
-
-```js
-export default {
- mounted() {
- this.$toast('Some messages');
- },
-};
-```
-
### Singleton
Toast use singleton mode by default, if you need to pop multiple Toast at the same time, you can refer to the following example:
```js
-Toast.allowMultiple();
+import { showToast, showSuccessToast, allowMultipleToast } from 'vant';
-const toast1 = Toast('First Toast');
-const toast2 = Toast.success('Second Toast');
+allowMultipleToast();
-toast1.clear();
-toast2.clear();
+const toast1 = showToast('First Toast');
+const toast2 = showSuccessToast('Second Toast');
+
+toast1.close();
+toast2.close();
```
### Set Default Options
-The Toast default configuration can be globally modified with the `Toast.setDefaultOptions` function.
+The Toast default configuration can be globally modified with the `setToastDefaultOptions` function.
```js
-Toast.setDefaultOptions({ duration: 2000 });
+import { setToastDefaultOptions, resetToastDefaultOptions } from 'vant';
-Toast.setDefaultOptions('loading', { forbidClick: true });
+setToastDefaultOptions({ duration: 2000 });
-Toast.resetDefaultOptions();
+setToastDefaultOptions('loading', { forbidClick: true });
-Toast.resetDefaultOptions('loading');
+resetToastDefaultOptions();
+
+resetToastDefaultOptions('loading');
+```
+
+### Use Toast Component
+
+If you want to render Vue components within a Toast, you can use the Toast component.
+
+```html
+
+
+
+
+
+```
+
+```js
+import { ref } from 'vue';
+
+export default {
+ setup() {
+ const show = ref(false);
+ return { show };
+ },
+};
```
## API
### Methods
-| Methods | Attribute | Return value | Description |
-| --- | --- | --- | --- |
-| Toast | `options \| message` | toast instance | Show toast |
-| Toast.loading | `options \| message` | toast instance | Show loading toast |
-| Toast.success | `options \| message` | toast instance | Show success toast |
-| Toast.fail | `options \| message` | toast instance | Show fail toast |
-| Toast.clear | `clearAll: boolean` | `void` | Close toast |
-| Toast.allowMultiple | - | `void` | Allow multiple toast at the same time |
-| Toast.setDefaultOptions | `type \| options` | `void` | Set default options of all toasts |
-| Toast.resetDefaultOptions | `type` | `void` | Reset default options of all toasts |
+Vant exports following Toast utility functions:
-### Options
+| Name | Description | Attribute | Return value |
+| --- | --- | --- | --- |
+| showToast | Show toast | `ToastOptions \| string` | toast instance |
+| showLoadingToast | Show loading toast | `ToastOptions \| string` | toast instance |
+| showSuccessToast | Show success toast | `ToastOptions \| string` | toast instance |
+| showFailToast | Show fail toast | `ToastOptions \| string` | toast instance |
+| closeToast | Close toast | `closeAll: boolean` | `void` |
+| allowMultipleToast | Allow multiple toast at the same time | - | `void` |
+| setToastDefaultOptions | Set default options of all toasts | `type \| ToastOptions` | `void` |
+| resetToastDefaultOptions | Reset default options of all toasts | `type` | `void` |
+
+### ToastOptions
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
@@ -175,6 +216,14 @@ Toast.resetDefaultOptions('loading');
| transition | Transition, equivalent to `name` prop of [transition](https://v3.vuejs.org/api/built-in-components.html#transition) | _string_ | `van-fade` |
| teleport | Specifies a target element where Toast will be mounted | _string \| Element_ | `body` |
+### Slots
+
+You can use following slots when using `Toast` component:
+
+| Name | Description |
+| ------- | -------------- |
+| message | Custom message |
+
### Types
The component exports the following type definitions:
@@ -196,8 +245,8 @@ The component provides the following CSS variables, which can be used to customi
| --van-toast-text-color | _var(--van-white)_ | - |
| --van-toast-loading-icon-color | _var(--van-white)_ | - |
| --van-toast-line-height | _var(--van-line-height-md)_ | - |
-| --van-toast-border-radius | _var(--van-border-radius-lg)_ | - |
-| --van-toast-background-color | _fade(var(--van-black), 70%)_ | - |
+| --van-toast-radius | _var(--van-radius-lg)_ | - |
+| --van-toast-background | _fade(var(--van-black), 70%)_ | - |
| --van-toast-icon-size | _36px_ | - |
| --van-toast-text-min-width | _96px_ | - |
| --van-toast-text-padding | _var(--van-padding-xs) var(--van-padding-sm)_ | - |
diff --git a/packages/vant/src/toast/README.zh-CN.md b/packages/vant/src/toast/README.zh-CN.md
index e18402388..b793b3005 100644
--- a/packages/vant/src/toast/README.zh-CN.md
+++ b/packages/vant/src/toast/README.zh-CN.md
@@ -16,30 +16,36 @@ const app = createApp();
app.use(Toast);
```
-#### 手动引入样式
+### 函数调用
-Toast 组件是以函数形式提供的,如果项目中使用 `unplugin-vue-components` 插件来自动引入组件样式,则无法正确识别 Toast 组件,因此需要手动引入 Toast 组件的样式:
+为了便于使用 `Toast`,Vant 提供了一系列辅助函数,通过辅助函数可以快速唤起全局的 Toast 组件。
+
+比如使用 `showToast` 函数,调用后会直接在页面中渲染对应的轻提示。
```js
-import 'vant/es/toast/style';
-```
+import { showToast } from 'vant';
-你可以在项目的入口文件或公共模块中引入 Toast 组件的样式,这样在业务代码中使用 Toast 时,便不再需要重复引入样式了。
+showToast('提示内容');
+```
## 代码演示
### 文字提示
```js
-Toast('提示内容');
+import { showToast } from 'vant';
+
+showToast('提示内容');
```
### 加载提示
-使用 `Toast.loading` 方法展示加载提示,通过 `forbidClick` 属性可以禁用背景点击。
+使用 `showLoadingToast` 方法展示加载提示,通过 `forbidClick` 选项可以禁用背景点击。
```js
-Toast.loading({
+import { showLoadingToast } from 'vant';
+
+showLoadingToast({
message: '加载中...',
forbidClick: true,
});
@@ -47,11 +53,13 @@ Toast.loading({
### 成功/失败提示
-使用 `Toast.success` 方法展示成功提示,使用 `Toast.fail` 方法展示失败提示。
+使用 `showSuccessToast` 方法展示成功提示,使用 `showFailToast` 方法展示失败提示。
```js
-Toast.success('成功文案');
-Toast.fail('失败文案');
+import { showSuccessToast, showFailToast } from 'vant';
+
+showSuccessToast('成功文案');
+showFailToast('失败文案');
```
### 自定义图标
@@ -59,12 +67,14 @@ Toast.fail('失败文案');
通过 `icon` 选项可以自定义图标,支持传入图标名称或图片链接,等同于 Icon 组件的 [name 属性](#/zh-CN/icon#props)。
```js
-Toast({
+import { showToast } from 'vant';
+
+showToast({
message: '自定义图标',
icon: 'like-o',
});
-Toast({
+showToast({
message: '自定义图片',
icon: 'https://fastly.jsdelivr.net/npm/@vant/assets/logo.png',
});
@@ -73,7 +83,9 @@ Toast({
通过`loadingType` 属性可以自定义加载图标类型。
```js
-Toast.loading({
+import { showLoadingToast } from 'vant';
+
+showLoadingToast({
message: '加载中...',
forbidClick: true,
loadingType: 'spinner',
@@ -85,12 +97,14 @@ Toast.loading({
Toast 默认渲染在屏幕正中位置,通过 `position` 属性可以控制 Toast 展示的位置。
```js
-Toast({
+import { showToast } from 'vant';
+
+showToast({
message: '顶部展示',
position: 'top',
});
-Toast({
+showToast({
message: '底部展示',
position: 'bottom',
});
@@ -101,7 +115,9 @@ Toast({
执行 Toast 方法时会返回对应的 Toast 实例,通过修改实例上的 `message` 属性可以实现动态更新提示的效果。
```js
-const toast = Toast.loading({
+import { showLoadingToast, closeToast } from 'vant';
+
+const toast = showLoadingToast({
duration: 0,
forbidClick: true,
message: '倒计时 3 秒',
@@ -114,70 +130,87 @@ const timer = setInterval(() => {
toast.message = `倒计时 ${second} 秒`;
} else {
clearInterval(timer);
- Toast.clear();
+ closeToast();
}
}, 1000);
```
-### 全局方法
-
-通过 `app.use` 全局注册 Toast 组件后,会自动在 app 的所有子组件上挂载 `$toast` 方法,便于在组件内调用。
-
-```js
-export default {
- mounted() {
- this.$toast('提示文案');
- },
-};
-```
-
-> Tips: 由于 setup 选项中无法访问 this,因此不能使用上述方式,请通过 import 引入。
-
### 单例模式
Toast 默认采用单例模式,即同一时间只会存在一个 Toast,如果需要在同一时间弹出多个 Toast,可以参考下面的示例:
```js
-Toast.allowMultiple();
+import { showToast, showSuccessToast, allowMultipleToast } from 'vant';
-const toast1 = Toast('第一个 Toast');
-const toast2 = Toast.success('第二个 Toast');
+allowMultipleToast();
-toast1.clear();
-toast2.clear();
+const toast1 = showToast('第一个 Toast');
+const toast2 = showSuccessToast('第二个 Toast');
+
+toast1.close();
+toast2.close();
```
### 修改默认配置
-通过 `Toast.setDefaultOptions` 函数可以全局修改 Toast 的默认配置。
+通过 `setToastDefaultOptions` 函数可以全局修改 `showToast` 等方法的默认配置。
```js
-Toast.setDefaultOptions({ duration: 2000 });
+import { setToastDefaultOptions, resetToastDefaultOptions } from 'vant';
-Toast.setDefaultOptions('loading', { forbidClick: true });
+setToastDefaultOptions({ duration: 2000 });
-Toast.resetDefaultOptions();
+setToastDefaultOptions('loading', { forbidClick: true });
-Toast.resetDefaultOptions('loading');
+resetToastDefaultOptions();
+
+resetToastDefaultOptions('loading');
+```
+
+### 使用 Toast 组件
+
+如果需要在 Toast 内嵌入组件或其他自定义内容,可以直接使用 Toast 组件,并使用 message 插槽进行定制。使用前需要通过 `app.use` 等方式注册组件。
+
+```html
+
+
+
+
+
+```
+
+```js
+import { ref } from 'vue';
+
+export default {
+ setup() {
+ const show = ref(false);
+ return { show };
+ },
+};
```
## API
### 方法
+Vant 中导出了以下 Toast 相关的辅助函数:
+
| 方法名 | 说明 | 参数 | 返回值 |
| --- | --- | --- | --- |
-| Toast | 展示提示 | `options \| message` | toast 实例 |
-| Toast.loading | 展示加载提示 | `options \| message` | toast 实例 |
-| Toast.success | 展示成功提示 | `options \| message` | toast 实例 |
-| Toast.fail | 展示失败提示 | `options \| message` | toast 实例 |
-| Toast.clear | 关闭提示 | `clearAll: boolean` | `void` |
-| Toast.allowMultiple | 允许同时存在多个 Toast | - | `void` |
-| Toast.setDefaultOptions | 修改默认配置,对所有 Toast 生效。
传入 type 可以修改指定类型的默认配置 | `type \| options` | `void` |
-| Toast.resetDefaultOptions | 重置默认配置,对所有 Toast 生效。
传入 type 可以重置指定类型的默认配置 | `type` | `void` |
+| showToast | 展示提示 | `ToastOptions \| string` | toast 实例 |
+| showLoadingToast | 展示加载提示 | `ToastOptions \| string` | toast 实例 |
+| showSuccessToast | 展示成功提示 | `ToastOptions \| string` | toast 实例 |
+| showFailToast | 展示失败提示 | `ToastOptions \| string` | toast 实例 |
+| closeToast | 关闭提示 | `closeAll: boolean` | `void` |
+| allowMultipleToast | 允许同时存在多个 Toast | - | `void` |
+| setToastDefaultOptions | 修改默认配置,影响所有的 `showToast` 调用。
传入 type 可以修改指定类型的默认配置 | `type \| ToastOptions` | `void` |
+| resetToastDefaultOptions | 重置默认配置,影响所有的 `showToast` 调用。
传入 type 可以重置指定类型的默认配置 | `type` | `void` |
### ToastOptions 数据结构
+调用 `showToast` 等方法时,支持传入以下选项:
+
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| type | 提示类型,可选值为 `loading` `success`
`fail` `html` | _ToastType_ | `text` |
@@ -200,6 +233,14 @@ Toast.resetDefaultOptions('loading');
| transition | 动画类名,等价于 [transition](https://v3.cn.vuejs.org/api/built-in-components.html#transition) 的`name`属性 | _string_ | `van-fade` |
| teleport | 指定挂载的节点,等同于 Teleport 组件的 [to 属性](https://v3.cn.vuejs.org/api/built-in-components.html#teleport) | _string \| Element_ | `body` |
+### Slots
+
+使用 `Toast` 组件时,支持以下插槽:
+
+| 名称 | 说明 |
+| ------- | -------------- |
+| message | 自定义文本内容 |
+
### 类型定义
组件导出以下类型定义:
@@ -221,8 +262,8 @@ import type { ToastType, ToastProps, ToastOptions, ToastPosition } from 'vant';
| --van-toast-text-color | _var(--van-white)_ | - |
| --van-toast-loading-icon-color | _var(--van-white)_ | - |
| --van-toast-line-height | _var(--van-line-height-md)_ | - |
-| --van-toast-border-radius | _var(--van-border-radius-lg)_ | - |
-| --van-toast-background-color | _fade(var(--van-black), 70%)_ | - |
+| --van-toast-radius | _var(--van-radius-lg)_ | - |
+| --van-toast-background | _fade(var(--van-black), 70%)_ | - |
| --van-toast-icon-size | _36px_ | - |
| --van-toast-text-min-width | _96px_ | - |
| --van-toast-text-padding | _var(--van-padding-xs) var(--van-padding-sm)_ | - |
@@ -231,3 +272,18 @@ import type { ToastType, ToastProps, ToastOptions, ToastPosition } from 'vant';
| --van-toast-default-min-height | _88px_ | - |
| --van-toast-position-top-distance | _20%_ | - |
| --van-toast-position-bottom-distance | _20%_ | - |
+
+## 常见问题
+
+### 引用 showToast 时出现编译报错?
+
+如果引用 `showToast` 方法时出现以下报错,说明项目中使用了 `babel-plugin-import` 插件,导致代码被错误编译。
+
+```bash
+These dependencies were not found:
+
+* vant/es/show-toast in ./src/xxx.js
+* vant/es/show-toast/style in ./src/xxx.js
+```
+
+Vant 从 4.0 版本开始不再支持 `babel-plugin-import` 插件,请参考 [迁移指南](#/zh-CN/migrate-from-v3#yi-chu-babel-plugin-import) 移除该插件。
diff --git a/packages/vant/src/toast/Toast.tsx b/packages/vant/src/toast/Toast.tsx
index 89213854f..7e92b4850 100644
--- a/packages/vant/src/toast/Toast.tsx
+++ b/packages/vant/src/toast/Toast.tsx
@@ -41,7 +41,7 @@ const popupInheritProps = [
'closeOnClickOverlay',
] as const;
-const toastProps = {
+export const toastProps = {
icon: String,
show: Boolean,
type: makeStringProp
('text'),
@@ -71,7 +71,7 @@ export default defineComponent({
emits: ['update:show'],
- setup(props, { emit }) {
+ setup(props, { emit, slots }) {
let timer: NodeJS.Timeout;
let clickable = false;
@@ -118,6 +118,10 @@ export default defineComponent({
const renderMessage = () => {
const { type, message } = props;
+ if (slots.message) {
+ return {slots.message()}
;
+ }
+
if (isDef(message) && message !== '') {
return type === 'html' ? (
diff --git a/packages/vant/src/toast/demo/index.vue b/packages/vant/src/toast/demo/index.vue
index e6812fc0a..6e7a48d7d 100644
--- a/packages/vant/src/toast/demo/index.vue
+++ b/packages/vant/src/toast/demo/index.vue
@@ -1,7 +1,15 @@
-
-
-
-
+
+
+
+
@@ -121,7 +134,7 @@ const showCustomizedToast = () => {
@@ -131,10 +144,20 @@ const showCustomizedToast = () => {
-
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/vant/src/toast/function-call.tsx b/packages/vant/src/toast/function-call.tsx
index 1628c3f58..b04ab6511 100644
--- a/packages/vant/src/toast/function-call.tsx
+++ b/packages/vant/src/toast/function-call.tsx
@@ -1,5 +1,5 @@
-import { ref, watch, getCurrentInstance, type App } from 'vue';
-import { extend, isObject, inBrowser, withInstall } from '../utils';
+import { ref, watch, getCurrentInstance } from 'vue';
+import { extend, isObject, inBrowser } from '../utils';
import { mountComponent, usePopupState } from '../utils/mount-component';
import VanToast from './Toast';
import type { ToastType, ToastOptions, ToastWrapperInstance } from './types';
@@ -71,7 +71,7 @@ function createInstance() {
return {
open,
- clear: close,
+ close,
message,
};
},
@@ -89,7 +89,7 @@ function getInstance() {
return queue[queue.length - 1];
}
-function Toast(options: string | ToastOptions = {}) {
+export function showToast(options: string | ToastOptions = {}) {
if (!inBrowser) {
return {} as ToastWrapperInstance;
}
@@ -110,30 +110,33 @@ function Toast(options: string | ToastOptions = {}) {
}
const createMethod = (type: ToastType) => (options: string | ToastOptions) =>
- Toast(extend({ type }, parseOptions(options)));
+ showToast(extend({ type }, parseOptions(options)));
-Toast.loading = createMethod('loading');
-Toast.success = createMethod('success');
-Toast.fail = createMethod('fail');
+export const showLoadingToast = createMethod('loading');
+export const showSuccessToast = createMethod('success');
+export const showFailToast = createMethod('fail');
-Toast.clear = (all?: boolean) => {
+export const closeToast = (all?: boolean) => {
if (queue.length) {
if (all) {
queue.forEach((toast) => {
- toast.clear();
+ toast.close();
});
queue = [];
} else if (!allowMultiple) {
- queue[0].clear();
+ queue[0].close();
} else {
- queue.shift()?.clear();
+ queue.shift()?.close();
}
}
};
-function setDefaultOptions(options: ToastOptions): void;
-function setDefaultOptions(type: ToastType, options: ToastOptions): void;
-function setDefaultOptions(
+export function setToastDefaultOptions(options: ToastOptions): void;
+export function setToastDefaultOptions(
+ type: ToastType,
+ options: ToastOptions
+): void;
+export function setToastDefaultOptions(
type: ToastType | ToastOptions,
options?: ToastOptions
) {
@@ -144,9 +147,7 @@ function setDefaultOptions(
}
}
-Toast.setDefaultOptions = setDefaultOptions;
-
-Toast.resetDefaultOptions = (type?: ToastType) => {
+export const resetToastDefaultOptions = (type?: ToastType) => {
if (typeof type === 'string') {
defaultOptionsMap.delete(type);
} else {
@@ -155,13 +156,6 @@ Toast.resetDefaultOptions = (type?: ToastType) => {
}
};
-Toast.allowMultiple = (value = true) => {
+export const allowMultipleToast = (value = true) => {
allowMultiple = value;
};
-
-Toast.install = (app: App) => {
- app.use(withInstall(VanToast));
- app.config.globalProperties.$toast = Toast;
-};
-
-export { Toast };
diff --git a/packages/vant/src/toast/index.less b/packages/vant/src/toast/index.less
index 9c19569cb..a075ed550 100644
--- a/packages/vant/src/toast/index.less
+++ b/packages/vant/src/toast/index.less
@@ -1,21 +1,19 @@
-@import './var.less';
-
-:root {
- --van-toast-max-width: @toast-max-width;
- --van-toast-font-size: @toast-font-size;
- --van-toast-text-color: @toast-text-color;
- --van-toast-loading-icon-color: @toast-loading-icon-color;
- --van-toast-line-height: @toast-line-height;
- --van-toast-border-radius: @toast-border-radius;
- --van-toast-background-color: @toast-background-color;
- --van-toast-icon-size: @toast-icon-size;
- --van-toast-text-min-width: @toast-text-min-width;
- --van-toast-text-padding: @toast-text-padding;
- --van-toast-default-padding: @toast-default-padding;
- --van-toast-default-width: @toast-default-width;
- --van-toast-default-min-height: @toast-default-min-height;
- --van-toast-position-top-distance: @toast-position-top-distance;
- --van-toast-position-bottom-distance: @toast-position-bottom-distance;
+body {
+ --van-toast-max-width: 70%;
+ --van-toast-font-size: var(--van-font-size-md);
+ --van-toast-text-color: var(--van-white);
+ --van-toast-loading-icon-color: var(--van-white);
+ --van-toast-line-height: var(--van-line-height-md);
+ --van-toast-radius: var(--van-radius-lg);
+ --van-toast-background: rgba(0, 0, 0, 0.7);
+ --van-toast-icon-size: 36px;
+ --van-toast-text-min-width: 96px;
+ --van-toast-text-padding: var(--van-padding-xs) var(--van-padding-sm);
+ --van-toast-default-padding: var(--van-padding-md);
+ --van-toast-default-width: 88px;
+ --van-toast-default-min-height: 88px;
+ --van-toast-position-top-distance: 20%;
+ --van-toast-position-bottom-distance: 20%;
}
.van-toast {
@@ -24,7 +22,7 @@
align-items: center;
justify-content: center;
box-sizing: content-box;
- transition: all var(--van-animation-duration-fast);
+ transition: all var(--van-duration-fast);
// hack for avoid max-width when use left & fixed
width: var(--van-toast-default-width);
@@ -40,8 +38,8 @@
text-align: center;
// https://github.com/vant-ui/vant/issues/8959
word-break: break-all;
- background: var(--van-toast-background-color);
- border-radius: var(--van-toast-border-radius);
+ background: var(--van-toast-background);
+ border-radius: var(--van-toast-radius);
&--unclickable {
// lock scroll
diff --git a/packages/vant/src/toast/index.ts b/packages/vant/src/toast/index.ts
index aeceb3d59..a43222c3f 100644
--- a/packages/vant/src/toast/index.ts
+++ b/packages/vant/src/toast/index.ts
@@ -1,6 +1,19 @@
-import { Toast } from './function-call';
+import { withInstall } from '../utils';
+import _Toast from './Toast';
+export const Toast = withInstall(_Toast);
export default Toast;
-export { Toast };
+export { toastProps } from './Toast';
+export {
+ showToast,
+ closeToast,
+ showFailToast,
+ showLoadingToast,
+ showSuccessToast,
+ allowMultipleToast,
+ setToastDefaultOptions,
+ resetToastDefaultOptions,
+} from './function-call';
+
export type { ToastProps } from './Toast';
export type { ToastType, ToastOptions, ToastPosition } from './types';
diff --git a/packages/vant/src/toast/test/__snapshots__/demo.spec.ts.snap b/packages/vant/src/toast/test/__snapshots__/demo.spec.ts.snap
index b2bbb1a92..f11efc1e7 100644
--- a/packages/vant/src/toast/test/__snapshots__/demo.spec.ts.snap
+++ b/packages/vant/src/toast/test/__snapshots__/demo.spec.ts.snap
@@ -129,4 +129,20 @@ exports[`should render demo and match snapshot 1`] = `