diff --git a/src/toast/index.js b/src/toast/index.js
index 947285b69..6515b04ba 100644
--- a/src/toast/index.js
+++ b/src/toast/index.js
@@ -1,6 +1,6 @@
-import { nextTick } from 'vue';
+import { ref, watch, nextTick } from 'vue';
import { isObject, inBrowser } from '../utils';
-import { mountComponent } from '../utils/mount-component';
+import { mountComponent, usePopupState } from '../utils/mount-component';
import VanToast from './Toast';
const defaultOptions = {
@@ -27,7 +27,7 @@ const defaultOptions = {
let defaultOptionsMap = {};
let queue = [];
-let multiple = false;
+let allowMultiple = false;
let currentOptions = {
...defaultOptions,
};
@@ -36,82 +36,73 @@ function parseOptions(message) {
if (isObject(message)) {
return message;
}
-
return { message };
}
-function isInDocument(element) {
- return document.body.contains(element);
+function createInstance() {
+ const { instance, unmount } = mountComponent({
+ setup() {
+ const message = ref();
+ const { state, toggle } = usePopupState();
+
+ const clear = () => {
+ toggle(false);
+ };
+
+ let timer;
+ const show = (duration) => {
+ toggle(true);
+ clearTimeout(timer);
+ if (duration > 0) {
+ timer = setTimeout(clear, duration);
+ }
+ };
+
+ const onClosed = () => {
+ if (allowMultiple) {
+ clearTimeout(timer);
+ queue = queue.filter((item) => item !== instance);
+ unmount();
+ }
+ };
+
+ watch(message, (value) => {
+ state.message = value;
+ });
+
+ return {
+ show,
+ clear,
+ state,
+ toggle,
+ message,
+ onClosed,
+ };
+ },
+ render() {
+ return (
+
+ );
+ },
+ });
+
+ return instance;
}
-function createInstance() {
+function getInstance() {
/* istanbul ignore if */
if (!inBrowser) {
return {};
}
- queue = queue.filter((item) => isInDocument(item.$el));
-
- if (!queue.length || multiple) {
- const { instance, unmount } = mountComponent({
- data() {
- return {
- timer: null,
- message: null,
- state: {
- show: false,
- },
- };
- },
- watch: {
- message(val) {
- this.state.message = val;
- },
- },
- methods: {
- clear() {
- this.toggle(false);
- },
- toggle(show, duration) {
- this.state.show = show;
-
- if (show) {
- clearTimeout(this.timer);
-
- if (duration > 0) {
- this.timer = setTimeout(() => {
- this.clear();
- }, duration);
- }
- }
- },
- setState(props) {
- this.state = {
- ...props,
- duration: undefined,
- };
- },
- onClosed() {
- if (multiple && inBrowser) {
- clearTimeout(this.timer);
- queue = queue.filter((item) => item !== this);
- unmount();
- }
- },
- },
- render() {
- return (
-
- );
- },
- });
-
+ if (!queue.length || allowMultiple) {
+ const instance = createInstance();
queue.push(instance);
}
@@ -119,7 +110,7 @@ function createInstance() {
}
function Toast(options = {}) {
- const toast = createInstance();
+ const toast = getInstance();
// should add z-index if previous toast has not disappeared
if (toast.value) {
@@ -133,10 +124,13 @@ function Toast(options = {}) {
...options,
};
- toast.setState(options);
+ toast.setState({
+ ...options,
+ duration: undefined,
+ });
nextTick(() => {
- toast.toggle(true, options.duration);
+ toast.show(options.duration);
});
return toast;
@@ -159,7 +153,7 @@ Toast.clear = (all) => {
toast.clear();
});
queue = [];
- } else if (!multiple) {
+ } else if (!allowMultiple) {
queue[0].clear();
} else {
queue.shift().clear();
@@ -185,7 +179,7 @@ Toast.resetDefaultOptions = (type) => {
};
Toast.allowMultiple = (value = true) => {
- multiple = value;
+ allowMultiple = value;
};
Toast.install = (app) => {