diff --git a/src/dialog/index.js b/src/dialog/index.js index 59cb3dca8..b51d4f90e 100644 --- a/src/dialog/index.js +++ b/src/dialog/index.js @@ -1,4 +1,3 @@ -import { nextTick } from 'vue'; import { inBrowser } from '../utils'; import { mountComponent, usePopupState } from '../utils/mount-component'; import VanDialog from './Dialog'; @@ -35,17 +34,13 @@ function Dialog(options) { initInstance(); } - instance.setState({ + instance.open({ ...Dialog.currentOptions, ...options, callback: (action) => { (action === 'confirm' ? resolve : reject)(action); }, }); - - nextTick(() => { - instance.toggle(true); - }); }); } diff --git a/src/image-preview/index.js b/src/image-preview/index.js index 61e6a88ef..b4e3fb9d8 100644 --- a/src/image-preview/index.js +++ b/src/image-preview/index.js @@ -1,4 +1,3 @@ -import { nextTick } from 'vue'; import { inBrowser } from '../utils'; import { mountComponent, usePopupState } from '../utils/mount-component'; import VanImagePreview from './ImagePreview'; @@ -60,15 +59,11 @@ const ImagePreview = (images, startPosition = 0) => { const options = Array.isArray(images) ? { images, startPosition } : images; - instance.setState({ + instance.open({ ...defaultConfig, ...options, }); - nextTick(() => { - instance.toggle(true); - }); - return instance; }; diff --git a/src/notify/index.js b/src/notify/index.js index 3cb333547..2c5a80065 100644 --- a/src/notify/index.js +++ b/src/notify/index.js @@ -1,4 +1,3 @@ -import { nextTick } from 'vue'; import { isObject, inBrowser } from '../utils'; import { mountComponent, usePopupState } from '../utils/mount-component'; import VanNotify from './Notify'; @@ -40,17 +39,13 @@ function Notify(options) { ...parseOptions(options), }; - instance.setState(options); + instance.open(options); clearTimeout(timer); if (options.duration && options.duration > 0) { timer = setTimeout(Notify.clear, options.duration); } - nextTick(() => { - instance.toggle(true); - }); - return instance; } diff --git a/src/toast/Toast.js b/src/toast/Toast.js index 72f18edeb..5304d6bcf 100644 --- a/src/toast/Toast.js +++ b/src/toast/Toast.js @@ -16,6 +16,7 @@ export default createComponent({ icon: String, show: Boolean, message: [Number, String], + duration: Number, className: null, iconPrefix: String, lockScroll: Boolean, @@ -39,6 +40,7 @@ export default createComponent({ emits: ['update:show'], setup(props, { emit }) { + let timer; let clickable; const toggleClickable = () => { @@ -55,6 +57,10 @@ export default createComponent({ } }; + const clearTimer = () => { + clearTimeout(timer); + }; + const renderIcon = () => { const { icon, type, iconPrefix, loadingType } = props; const hasIcon = icon || type === 'success' || type === 'fail'; @@ -88,6 +94,18 @@ export default createComponent({ watch([() => props.show, () => props.forbidClick], toggleClickable); + watch( + () => props.show, + (value) => { + clearTimer(); + if (value && props.duration > 0) { + timer = setTimeout(() => { + emit('update:show', false); + }, props.duration); + } + } + ); + onMounted(toggleClickable); onUnmounted(toggleClickable); @@ -100,6 +118,7 @@ export default createComponent({ ]} transition={props.transition} onClick={onClick} + onClosed={clearTimer} > {renderIcon()} {renderMessage()} diff --git a/src/toast/index.js b/src/toast/index.js index 6515b04ba..7f4f4a9c3 100644 --- a/src/toast/index.js +++ b/src/toast/index.js @@ -1,4 +1,4 @@ -import { ref, watch, nextTick } from 'vue'; +import { ref, watch } from 'vue'; import { isObject, inBrowser } from '../utils'; import { mountComponent, usePopupState } from '../utils/mount-component'; import VanToast from './Toast'; @@ -25,7 +25,6 @@ const defaultOptions = { // default options of specific type let defaultOptionsMap = {}; - let queue = []; let allowMultiple = false; let currentOptions = { @@ -43,24 +42,14 @@ function createInstance() { const { instance, unmount } = mountComponent({ setup() { const message = ref(); - const { state, toggle } = usePopupState(); + const { open, 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(); } @@ -71,7 +60,7 @@ function createInstance() { }); return { - show, + open, clear, state, toggle, @@ -112,11 +101,6 @@ function getInstance() { function Toast(options = {}) { const toast = getInstance(); - // should add z-index if previous toast has not disappeared - if (toast.value) { - toast.updateZIndex(); - } - options = parseOptions(options); options = { ...currentOptions, @@ -124,14 +108,7 @@ function Toast(options = {}) { ...options, }; - toast.setState({ - ...options, - duration: undefined, - }); - - nextTick(() => { - toast.show(options.duration); - }); + toast.open(options); return toast; } diff --git a/src/utils/mount-component.ts b/src/utils/mount-component.ts index 5c20326ab..bdbf7c9be 100644 --- a/src/utils/mount-component.ts +++ b/src/utils/mount-component.ts @@ -1,4 +1,4 @@ -import { createApp, reactive, Component } from 'vue'; +import { createApp, reactive, Component, nextTick } from 'vue'; import { usePublicApi } from '../composition/use-public-api'; export function usePopupState() { @@ -10,17 +10,22 @@ export function usePopupState() { state.show = show; }; + const open = (props: Record) => { + Object.assign(state, props); + + nextTick(() => { + toggle(true); + }); + }; + const close = () => { toggle(false); }; - const setState = (props: Record) => { - Object.assign(state, props); - }; - - usePublicApi({ close, toggle, setState }); + usePublicApi({ open, close, toggle }); return { + open, state, toggle, };