mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-10-05 00:09:58 +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
|
||||||
|
|
||||||
| Methods | Attribute | Return value | Description |
|
| Methods | Attribute | Return value | Description |
|
||||||
@ -70,9 +83,10 @@ export default {
|
|||||||
| Toast.loading | `options | message` | toast instance | Show loading toast |
|
| Toast.loading | `options | message` | toast instance | Show loading toast |
|
||||||
| Toast.success | `options | message` | toast instance | Show success toast |
|
| Toast.success | `options | message` | toast instance | Show success toast |
|
||||||
| Toast.fail | `options | message` | toast instance | Show fail 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.setDefaultOptions | `options` | `void` | Set default options of all toasts |
|
||||||
| Toast.resetDefaultOptions | - | `void` | Reset default options of all toasts |
|
| Toast.resetDefaultOptions | - | `void` | Reset default options of all toasts |
|
||||||
| Toast.clear | - | `void` | Close |
|
|
||||||
|
|
||||||
### Options
|
### 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.loading | `options | message` | toast 实例 | 展示加载提示 |
|
||||||
| Toast.success | `options | message` | toast 实例 | 展示成功提示 |
|
| Toast.success | `options | message` | toast 实例 | 展示成功提示 |
|
||||||
| Toast.fail | `options | message` | toast 实例 | 展示失败提示 |
|
| Toast.fail | `options | message` | toast 实例 | 展示失败提示 |
|
||||||
|
| Toast.clear | `clearAll` | `void` | 关闭提示 |
|
||||||
|
| Toast.allowMultiple | - | `void` | 允许同时存在多个 Toast |
|
||||||
| Toast.setDefaultOptions | `options` | `void` | 修改默认配置,对所有 Toast 生效 |
|
| Toast.setDefaultOptions | `options` | `void` | 修改默认配置,对所有 Toast 生效 |
|
||||||
| Toast.resetDefaultOptions | - | `void` | 重置默认配置,对所有 Toast 生效 |
|
| Toast.resetDefaultOptions | - | `void` | 重置默认配置,对所有 Toast 生效 |
|
||||||
| Toast.clear | - | `void` | 关闭提示 |
|
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
@ -1,77 +1,88 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import VueToast from './toast';
|
import VueToast from './toast';
|
||||||
|
|
||||||
let instance;
|
|
||||||
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
mask: false,
|
mask: false,
|
||||||
|
message: '',
|
||||||
visible: true,
|
visible: true,
|
||||||
duration: 3000,
|
duration: 3000,
|
||||||
position: 'middle',
|
position: 'middle',
|
||||||
forbidClick: false,
|
forbidClick: false
|
||||||
clear: () => {
|
|
||||||
instance.visible = false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
const parseOptions = message => typeof message === 'object' ? message : { message };
|
||||||
|
|
||||||
let currentDefaultOptions = {
|
let queue = [];
|
||||||
...defaultOptions
|
let singleton = true;
|
||||||
};
|
let currentOptions = { ...defaultOptions };
|
||||||
|
|
||||||
const createInstance = () => {
|
function createInstance() {
|
||||||
if (!instance) {
|
if (!queue.length || !singleton) {
|
||||||
const ToastConstructor = Vue.extend(VueToast);
|
const toast = new (Vue.extend(VueToast))({
|
||||||
instance = new ToastConstructor({
|
|
||||||
el: document.createElement('div')
|
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 = {}) => {
|
function Toast(options = {}) {
|
||||||
createInstance();
|
const toast = createInstance();
|
||||||
|
|
||||||
options = typeof options === 'object' ? options : { message: options };
|
options = {
|
||||||
options = { ...currentDefaultOptions, ...options };
|
...currentOptions,
|
||||||
Object.assign(instance, options);
|
...parseOptions(options),
|
||||||
|
clear() {
|
||||||
|
toast.visible = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
clearTimeout(instance.timer);
|
Object.assign(toast, options);
|
||||||
|
clearTimeout(toast.timer);
|
||||||
|
|
||||||
if (options.duration !== 0) {
|
if (options.duration > 0) {
|
||||||
instance.timer = setTimeout(() => {
|
toast.timer = setTimeout(() => {
|
||||||
instance.clear();
|
toast.clear();
|
||||||
}, options.duration);
|
}, options.duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance;
|
return toast;
|
||||||
};
|
};
|
||||||
|
|
||||||
const createMethod = type => (options = {}) => Toast({
|
const createMethod = type => options => Toast({
|
||||||
type,
|
type, ...parseOptions(options)
|
||||||
message: typeof options === 'object' ? options.message : options,
|
|
||||||
...options
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Toast.loading = createMethod('loading');
|
['loading', 'success', 'fail'].forEach(method => {
|
||||||
Toast.success = createMethod('success');
|
Toast[method] = createMethod(method);
|
||||||
Toast.fail = createMethod('fail');
|
});
|
||||||
|
|
||||||
Toast.clear = () => {
|
Toast.clear = all => {
|
||||||
instance && instance.clear();
|
if (queue.length) {
|
||||||
|
if (all) {
|
||||||
|
queue.forEach(toast => {
|
||||||
|
toast.clear();
|
||||||
|
});
|
||||||
|
queue = [];
|
||||||
|
} else if (singleton) {
|
||||||
|
queue[0].clear();
|
||||||
|
} else {
|
||||||
|
queue.shift().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Toast.setDefaultOptions = (options = {}) => {
|
Toast.setDefaultOptions = options => {
|
||||||
currentDefaultOptions = {
|
Object.assign(currentOptions, options);
|
||||||
...currentDefaultOptions,
|
|
||||||
...options
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Toast.resetDefaultOptions = () => {
|
Toast.resetDefaultOptions = () => {
|
||||||
currentDefaultOptions = {
|
currentOptions = { ...defaultOptions };
|
||||||
...defaultOptions
|
};
|
||||||
};
|
|
||||||
|
Toast.allowMultiple = (allow = true) => {
|
||||||
|
singleton = !allow;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vue.prototype.$toast = Toast;
|
Vue.prototype.$toast = Toast;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { create } from '../utils';
|
import { create } from '../utils';
|
||||||
|
|
||||||
const DEFAULT_STYLE_LIST = ['success', 'fail', 'loading'];
|
const STYLE_LIST = ['success', 'fail', 'loading'];
|
||||||
|
|
||||||
export default create({
|
export default create({
|
||||||
name: 'van-toast',
|
name: 'van-toast',
|
||||||
@ -48,7 +48,7 @@ export default create({
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
displayStyle() {
|
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', () => {
|
describe('Toast', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
Toast.clear();
|
Toast.clear(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('create a empty toast', () => {
|
it('create a empty toast', () => {
|
||||||
@ -87,28 +87,49 @@ describe('Toast', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('toast disappeared after duration', (done) => {
|
it('toast disappeared after duration', (done) => {
|
||||||
Toast({
|
const toast = Toast({
|
||||||
message: 'toast',
|
message: 'toast',
|
||||||
duration: 10
|
duration: 10
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(document.querySelector('.van-toast-wrapper').style.display === 'none').to.be.false;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
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();
|
done();
|
||||||
}, 500);
|
}, 500);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('toast duration 0', (done) => {
|
it('toast duration 0', () => {
|
||||||
Toast({
|
Toast.allowMultiple();
|
||||||
|
const toast = Toast({
|
||||||
message: 'toast',
|
message: 'toast',
|
||||||
duration: 0
|
duration: 0
|
||||||
});
|
});
|
||||||
|
expect(toast.timer).to.equal(undefined);
|
||||||
|
Toast.allowMultiple(false);
|
||||||
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
it('multiple toast', () => {
|
||||||
expect(document.querySelector('.van-toast-wrapper').style.display === 'none').to.be.false;
|
Toast.allowMultiple();
|
||||||
done();
|
Toast.clear(true);
|
||||||
}, 500);
|
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