[new feature] Toast: support multiple instance (#586)

This commit is contained in:
neverland
2018-01-29 17:19:01 +08:00
committed by GitHub
parent 7f055a4d2d
commit 1f19852118
5 changed files with 115 additions and 56 deletions
+52 -41
View File
@@ -1,77 +1,88 @@
import Vue from 'vue';
import VueToast from './toast';
let instance;
const defaultOptions = {
type: 'text',
mask: false,
message: '',
visible: true,
duration: 3000,
position: 'middle',
forbidClick: false,
clear: () => {
instance.visible = false;
}
forbidClick: false
};
const parseOptions = message => typeof message === 'object' ? message : { message };
let currentDefaultOptions = {
...defaultOptions
};
let queue = [];
let singleton = true;
let currentOptions = { ...defaultOptions };
const createInstance = () => {
if (!instance) {
const ToastConstructor = Vue.extend(VueToast);
instance = new ToastConstructor({
function createInstance() {
if (!queue.length || !singleton) {
const toast = new (Vue.extend(VueToast))({
el: document.createElement('div')
});
document.body.appendChild(instance.$el);
document.body.appendChild(toast.$el);
queue.push(toast);
}
return queue[queue.length - 1];
};
const Toast = (options = {}) => {
createInstance();
function Toast(options = {}) {
const toast = createInstance();
options = typeof options === 'object' ? options : { message: options };
options = { ...currentDefaultOptions, ...options };
Object.assign(instance, options);
options = {
...currentOptions,
...parseOptions(options),
clear() {
toast.visible = false;
}
};
clearTimeout(instance.timer);
Object.assign(toast, options);
clearTimeout(toast.timer);
if (options.duration !== 0) {
instance.timer = setTimeout(() => {
instance.clear();
if (options.duration > 0) {
toast.timer = setTimeout(() => {
toast.clear();
}, options.duration);
}
return instance;
return toast;
};
const createMethod = type => (options = {}) => Toast({
type,
message: typeof options === 'object' ? options.message : options,
...options
const createMethod = type => options => Toast({
type, ...parseOptions(options)
});
Toast.loading = createMethod('loading');
Toast.success = createMethod('success');
Toast.fail = createMethod('fail');
['loading', 'success', 'fail'].forEach(method => {
Toast[method] = createMethod(method);
});
Toast.clear = () => {
instance && instance.clear();
Toast.clear = all => {
if (queue.length) {
if (all) {
queue.forEach(toast => {
toast.clear();
});
queue = [];
} else if (singleton) {
queue[0].clear();
} else {
queue.shift().clear();
}
}
};
Toast.setDefaultOptions = (options = {}) => {
currentDefaultOptions = {
...currentDefaultOptions,
...options
};
Toast.setDefaultOptions = options => {
Object.assign(currentOptions, options);
};
Toast.resetDefaultOptions = () => {
currentDefaultOptions = {
...defaultOptions
};
currentOptions = { ...defaultOptions };
};
Toast.allowMultiple = (allow = true) => {
singleton = !allow;
};
Vue.prototype.$toast = Toast;
+2 -2
View File
@@ -21,7 +21,7 @@
<script>
import { create } from '../utils';
const DEFAULT_STYLE_LIST = ['success', 'fail', 'loading'];
const STYLE_LIST = ['success', 'fail', 'loading'];
export default create({
name: 'van-toast',
@@ -48,7 +48,7 @@ export default create({
computed: {
displayStyle() {
return DEFAULT_STYLE_LIST.indexOf(this.type) !== -1 ? 'default' : this.type;
return STYLE_LIST.indexOf(this.type) !== -1 ? 'default' : this.type;
}
}
});