使用场景
弹窗在业务中经常会用到,Vue中,我们要实现一个复杂弹窗,通常需要三步:
- 定义弹窗文件,写出弹窗的样式;
- 在页面中引入弹窗组件;
- 通过visible属性来控制弹窗的显示和隐藏;
这种方式比较基础,也比较繁琐。试想一下,如果我们多个页面都需要这个弹窗,这时候就会有很多冗余的代码。而这个小工具类,就是为了让我们像alert一样的丝滑的使用弹窗。
实现
因为弹窗大致可以分为两类:confirm/alert.
- Confirm 弹窗有两种状态:sure/cancel
- Alert 弹窗只有一种状态:sure
因此,我们可以用Promise的方式来调用我们的弹窗。
// confirm dialog
myConfirm.show(opts).then(res => {
// click sure button
}).catch(err => {
// click cancel button
});
// alert dialog
myAlert.show(opts).then(res => {
// close alert dialog.
});
当然,这里如果有超过两种状态的弹窗,也可以通过resolve函数传入不同的状态值来实现。
工具类实现:
import Vue from 'vue'
class DialogService {
instance = null
Comp = null
vueOpts = null
constructor(Comp, vueOpts) {
this.Comp = Comp
this.vueOpts = vueOpts || {}
}
__initDialog(Comp) {
const CompVue = Vue.extend(Comp)
this.instance = new CompVue({
el: document.createElement('div'),
...this.vueOpts,
})
document.body.appendChild(this.instance.$el)
}
__destroyDialog() {
document.body.removeChild(this.instance.$el)
this.instance = null
}
show(options) {
this.__initDialog(this.Comp)
return new Promise((resolve, reject) => {
this.instance.show(options)
const _resolve = this.instance.resolve.bind(this)
const _reject = this.instance.reject.bind(this)
this.instance.resolve = async res => {
const _res = await _resolve(res)
resolve(_res)
this.__destroyDialog()
}
this.instance.reject = async res => {
const _res = await _reject(res)
reject(_res)
this.__destroyDialog()
}
})
}
}
export const dialogServiceMixins = {
data() {
return {
visible: false
}
},
methods: {
show() {
this.visible = true;
},
resolve() {},
reject() {}
}
}
export default DialogService
如何调用:
import DialogService from './DialogService';
import ConfirmDialogComp from './ConfirmDialog';
const confirmDialog = new DialogService(ConfirmDialog);
confirmDialog.show();