refactor(Toast): usePopupState

This commit is contained in:
chenjiahan 2020-08-31 20:19:08 +08:00
parent 10355ed849
commit c4921da290

View File

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