refactor: update usePopupState

This commit is contained in:
chenjiahan 2020-09-01 09:47:59 +08:00
parent c4921da290
commit 6e6cfe5c65
6 changed files with 37 additions and 51 deletions

View File

@ -1,4 +1,3 @@
import { nextTick } from 'vue';
import { inBrowser } from '../utils'; import { inBrowser } from '../utils';
import { mountComponent, usePopupState } from '../utils/mount-component'; import { mountComponent, usePopupState } from '../utils/mount-component';
import VanDialog from './Dialog'; import VanDialog from './Dialog';
@ -35,17 +34,13 @@ function Dialog(options) {
initInstance(); initInstance();
} }
instance.setState({ instance.open({
...Dialog.currentOptions, ...Dialog.currentOptions,
...options, ...options,
callback: (action) => { callback: (action) => {
(action === 'confirm' ? resolve : reject)(action); (action === 'confirm' ? resolve : reject)(action);
}, },
}); });
nextTick(() => {
instance.toggle(true);
});
}); });
} }

View File

@ -1,4 +1,3 @@
import { nextTick } from 'vue';
import { inBrowser } from '../utils'; import { inBrowser } from '../utils';
import { mountComponent, usePopupState } from '../utils/mount-component'; import { mountComponent, usePopupState } from '../utils/mount-component';
import VanImagePreview from './ImagePreview'; import VanImagePreview from './ImagePreview';
@ -60,15 +59,11 @@ const ImagePreview = (images, startPosition = 0) => {
const options = Array.isArray(images) ? { images, startPosition } : images; const options = Array.isArray(images) ? { images, startPosition } : images;
instance.setState({ instance.open({
...defaultConfig, ...defaultConfig,
...options, ...options,
}); });
nextTick(() => {
instance.toggle(true);
});
return instance; return instance;
}; };

View File

@ -1,4 +1,3 @@
import { nextTick } from 'vue';
import { isObject, inBrowser } from '../utils'; import { isObject, inBrowser } from '../utils';
import { mountComponent, usePopupState } from '../utils/mount-component'; import { mountComponent, usePopupState } from '../utils/mount-component';
import VanNotify from './Notify'; import VanNotify from './Notify';
@ -40,17 +39,13 @@ function Notify(options) {
...parseOptions(options), ...parseOptions(options),
}; };
instance.setState(options); instance.open(options);
clearTimeout(timer); clearTimeout(timer);
if (options.duration && options.duration > 0) { if (options.duration && options.duration > 0) {
timer = setTimeout(Notify.clear, options.duration); timer = setTimeout(Notify.clear, options.duration);
} }
nextTick(() => {
instance.toggle(true);
});
return instance; return instance;
} }

View File

@ -16,6 +16,7 @@ export default createComponent({
icon: String, icon: String,
show: Boolean, show: Boolean,
message: [Number, String], message: [Number, String],
duration: Number,
className: null, className: null,
iconPrefix: String, iconPrefix: String,
lockScroll: Boolean, lockScroll: Boolean,
@ -39,6 +40,7 @@ export default createComponent({
emits: ['update:show'], emits: ['update:show'],
setup(props, { emit }) { setup(props, { emit }) {
let timer;
let clickable; let clickable;
const toggleClickable = () => { const toggleClickable = () => {
@ -55,6 +57,10 @@ export default createComponent({
} }
}; };
const clearTimer = () => {
clearTimeout(timer);
};
const renderIcon = () => { const renderIcon = () => {
const { icon, type, iconPrefix, loadingType } = props; const { icon, type, iconPrefix, loadingType } = props;
const hasIcon = icon || type === 'success' || type === 'fail'; const hasIcon = icon || type === 'success' || type === 'fail';
@ -88,6 +94,18 @@ export default createComponent({
watch([() => props.show, () => props.forbidClick], toggleClickable); 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); onMounted(toggleClickable);
onUnmounted(toggleClickable); onUnmounted(toggleClickable);
@ -100,6 +118,7 @@ export default createComponent({
]} ]}
transition={props.transition} transition={props.transition}
onClick={onClick} onClick={onClick}
onClosed={clearTimer}
> >
{renderIcon()} {renderIcon()}
{renderMessage()} {renderMessage()}

View File

@ -1,4 +1,4 @@
import { ref, watch, nextTick } from 'vue'; import { ref, watch } from 'vue';
import { isObject, inBrowser } from '../utils'; import { isObject, inBrowser } from '../utils';
import { mountComponent, usePopupState } from '../utils/mount-component'; import { mountComponent, usePopupState } from '../utils/mount-component';
import VanToast from './Toast'; import VanToast from './Toast';
@ -25,7 +25,6 @@ const defaultOptions = {
// default options of specific type // default options of specific type
let defaultOptionsMap = {}; let defaultOptionsMap = {};
let queue = []; let queue = [];
let allowMultiple = false; let allowMultiple = false;
let currentOptions = { let currentOptions = {
@ -43,24 +42,14 @@ function createInstance() {
const { instance, unmount } = mountComponent({ const { instance, unmount } = mountComponent({
setup() { setup() {
const message = ref(); const message = ref();
const { state, toggle } = usePopupState(); const { open, state, toggle } = usePopupState();
const clear = () => { const clear = () => {
toggle(false); toggle(false);
}; };
let timer;
const show = (duration) => {
toggle(true);
clearTimeout(timer);
if (duration > 0) {
timer = setTimeout(clear, duration);
}
};
const onClosed = () => { const onClosed = () => {
if (allowMultiple) { if (allowMultiple) {
clearTimeout(timer);
queue = queue.filter((item) => item !== instance); queue = queue.filter((item) => item !== instance);
unmount(); unmount();
} }
@ -71,7 +60,7 @@ function createInstance() {
}); });
return { return {
show, open,
clear, clear,
state, state,
toggle, toggle,
@ -112,11 +101,6 @@ function getInstance() {
function Toast(options = {}) { function Toast(options = {}) {
const toast = getInstance(); const toast = getInstance();
// should add z-index if previous toast has not disappeared
if (toast.value) {
toast.updateZIndex();
}
options = parseOptions(options); options = parseOptions(options);
options = { options = {
...currentOptions, ...currentOptions,
@ -124,14 +108,7 @@ function Toast(options = {}) {
...options, ...options,
}; };
toast.setState({ toast.open(options);
...options,
duration: undefined,
});
nextTick(() => {
toast.show(options.duration);
});
return toast; return toast;
} }

View File

@ -1,4 +1,4 @@
import { createApp, reactive, Component } from 'vue'; import { createApp, reactive, Component, nextTick } from 'vue';
import { usePublicApi } from '../composition/use-public-api'; import { usePublicApi } from '../composition/use-public-api';
export function usePopupState() { export function usePopupState() {
@ -10,17 +10,22 @@ export function usePopupState() {
state.show = show; state.show = show;
}; };
const open = (props: Record<string, any>) => {
Object.assign(state, props);
nextTick(() => {
toggle(true);
});
};
const close = () => { const close = () => {
toggle(false); toggle(false);
}; };
const setState = (props: Record<string, any>) => { usePublicApi({ open, close, toggle });
Object.assign(state, props);
};
usePublicApi({ close, toggle, setState });
return { return {
open,
state, state,
toggle, toggle,
}; };