mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] Toast: support multiple instance (#586)
This commit is contained in:
parent
7f055a4d2d
commit
1f19852118
@ -62,6 +62,19 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
#### Singleton
|
||||
Toast use singleton mode by default, if you need to pop multiple Toast at the same time, you can refer to the following example
|
||||
|
||||
```js
|
||||
Toast.allowMultiple();
|
||||
|
||||
const toast1 = Toast('First Toast');
|
||||
const toast2 = Toast.success('Second Toast');
|
||||
|
||||
toast1.clear();
|
||||
toast2.clear();
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
| Methods | Attribute | Return value | Description |
|
||||
@ -70,9 +83,10 @@ export default {
|
||||
| Toast.loading | `options | message` | toast instance | Show loading toast |
|
||||
| Toast.success | `options | message` | toast instance | Show success toast |
|
||||
| Toast.fail | `options | message` | toast instance | Show fail toast |
|
||||
| Toast.clear | `clearAll` | `void` | Close |
|
||||
| Toast.allowMultiple | - | `void` | Allow multlple toast at the same time |
|
||||
| Toast.setDefaultOptions | `options` | `void` | Set default options of all toasts |
|
||||
| Toast.resetDefaultOptions | - | `void` | Reset default options of all toasts |
|
||||
| Toast.clear | - | `void` | Close |
|
||||
|
||||
### Options
|
||||
|
||||
|
@ -62,6 +62,18 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
#### 单例模式
|
||||
Toast 默认采用单例模式,即同一时间只会存在一个 Toast,如果需要在同一时间弹出多个 Toast,可以参考下面的示例
|
||||
|
||||
```js
|
||||
Toast.allowMultiple();
|
||||
|
||||
const toast1 = Toast('第一个 Toast');
|
||||
const toast2 = Toast.success('第二个 Toast');
|
||||
|
||||
toast1.clear();
|
||||
toast2.clear();
|
||||
```
|
||||
|
||||
|
||||
### 方法
|
||||
@ -72,9 +84,10 @@ export default {
|
||||
| Toast.loading | `options | message` | toast 实例 | 展示加载提示 |
|
||||
| Toast.success | `options | message` | toast 实例 | 展示成功提示 |
|
||||
| Toast.fail | `options | message` | toast 实例 | 展示失败提示 |
|
||||
| Toast.clear | `clearAll` | `void` | 关闭提示 |
|
||||
| Toast.allowMultiple | - | `void` | 允许同时存在多个 Toast |
|
||||
| Toast.setDefaultOptions | `options` | `void` | 修改默认配置,对所有 Toast 生效 |
|
||||
| Toast.resetDefaultOptions | - | `void` | 重置默认配置,对所有 Toast 生效 |
|
||||
| Toast.clear | - | `void` | 关闭提示 |
|
||||
|
||||
### Options
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ import Toast from 'packages/toast';
|
||||
|
||||
describe('Toast', () => {
|
||||
afterEach(() => {
|
||||
Toast.clear();
|
||||
Toast.clear(true);
|
||||
});
|
||||
|
||||
it('create a empty toast', () => {
|
||||
@ -87,28 +87,49 @@ describe('Toast', () => {
|
||||
});
|
||||
|
||||
it('toast disappeared after duration', (done) => {
|
||||
Toast({
|
||||
const toast = Toast({
|
||||
message: 'toast',
|
||||
duration: 10
|
||||
});
|
||||
|
||||
expect(document.querySelector('.van-toast-wrapper').style.display === 'none').to.be.false;
|
||||
|
||||
setTimeout(() => {
|
||||
expect(document.querySelector('.van-toast-wrapper').style.display === 'none').to.be.true;
|
||||
expect(toast.$el.style.display === 'none').to.be.true;
|
||||
Toast.clear();
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('toast duration 0', (done) => {
|
||||
Toast({
|
||||
it('toast duration 0', () => {
|
||||
Toast.allowMultiple();
|
||||
const toast = Toast({
|
||||
message: 'toast',
|
||||
duration: 0
|
||||
});
|
||||
expect(toast.timer).to.equal(undefined);
|
||||
Toast.allowMultiple(false);
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
expect(document.querySelector('.van-toast-wrapper').style.display === 'none').to.be.false;
|
||||
done();
|
||||
}, 500);
|
||||
it('multiple toast', () => {
|
||||
Toast.allowMultiple();
|
||||
Toast.clear(true);
|
||||
const toast1 = Toast.success('1');
|
||||
const toast2 = Toast.success('2');
|
||||
Toast.clear();
|
||||
expect(toast1.visible).to.be.false;
|
||||
expect(toast2.visible).to.be.true;
|
||||
Toast.clear();
|
||||
Toast.clear();
|
||||
expect(toast2.visible).to.be.false;
|
||||
Toast.allowMultiple(false);
|
||||
});
|
||||
|
||||
it('set default options', () => {
|
||||
Toast.setDefaultOptions({ duration: 1000 });
|
||||
const toast1 = Toast(1);
|
||||
expect(toast1.duration).to.equal(1000);
|
||||
|
||||
Toast.resetDefaultOptions();
|
||||
const toast2 = Toast(1);
|
||||
expect(toast2.duration).to.equal(3000);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user