原由
通常在业务中,写抽屉组件或者弹框组件的时候,都是用 visible 属性来控制是否显示:
Open Modal with async logic
{{ ModalText }}
这种写法在组件比较简单,逻辑不多的时候还好,当这个页面又许多弹框,或者当前页面组件本身就比较复杂的时候,各种 isXXVisible 充斥在当前页面中,让人看着就无力维护...
还有一个场景,一个列表有个查看详情按钮,点击会打开一个详情抽屉,这个详情抽屉里又有一个列表,也能打开另一个详情抽屉,以此类推。没法确定要打开的弹窗的数量,也就没法提前在父组件中写好弹窗...
从逻辑上来说,这种用一个变量来控制组件显隐的做法,是把弹窗或抽屉组件当成了当前组件的一个子组件。但是在绝大多数情况下,弹窗或抽屉的内容跟原组件都没太大关联,比如抽屉打开详情页,比如弹窗打开一个表单等等,逻辑上更像是一个独立的子应用那样,这个子应用接收调起它的父应用传过来的一些参数,但之后整个页面的控制权就应该交给这个子应用(弹窗或抽屉),主应用应该只是监听 子应用 退出的事件(回调结果)后作出相应的响应才对。
因此,我的想法是通过调用一个函数,并传入一些相应的props参数来创建弹窗或者抽屉,同时提供回调函数在弹窗提交结果或者取消时进行响应。这样我们可以很方便的把弹窗的逻辑内聚到弹窗组件上,而不用在父组件里写很多和父组件无关的逻辑。
函数用法介绍
1. createAntdDrawer
默认会往 title 和 content 这两个 slot 插槽内传入一个名为 close
的函数,在子组件内使用 this.$emit('close', payload)
触发关闭行为
createAntdDrawer({
// antd drawer 的所有props
drawerProps: {},
// title slot
// drawerProps.title 和 title 同时存在的话,优先使用 title
title: {
template: Title,
props: {
title: '自定义标题组件',
},
},
// default slot
content: {
template: HelloWorld,
props: {
msg: 'Welcome to Your Vue.js App',
},
},
// 关闭前调用 支持async
beforeClose: function() {
console.log('我要关闭了');
},
// 关闭后调用 支持async
afterClose: function() {
console.log('我已经关闭了');
},
});
2. createAntdModal
会往 title、content 和 footer 这三个 slot 插槽内传入 close
、ok
两个函数和 confirmLoading
这一状态, 在子组件内使用 this.$emit('close', payload)
触发关闭动作, 使用 this.$emit('ok', payload)
触发 onOk
回调。子组件内可以使用 confirmLoading
来管理确定按钮的加载状态
createAntdModal({
// antd modal 的所有props
modalProps: {},
// title slot
// modalProps.title 和 title 同时存在的话,优先使用 title
title: {
template: Title,
props: {
title: '自定义标题组件',
},
},
// content slot
content: {
template: HelloWorld,
props: {
msg: 'Welcome to Your Vue.js App',
},
},
// footer slot
footer: {
template: Footer,
props: {
cancelText: 'hahah取消',
okText: 'hahah确定',
},
},
// 关闭前调用 支持async
beforeClose: function() {
console.log('我要关闭了');
},
// 关闭后调用 支持async
afterClose: function() {
console.log('我已经关闭了');
},
// 确定按钮回调 支持async
async onOk() {
await new Promise((resolve) => {
setTimeout(() => {
console.log('点了确定');
resolve();
}, 3000);
});
},
});
git地址
https://github.com/hzyhbk/cre...
clone 整个项目,安装下依赖,然后 npm run serve
,会在首页看到两个按钮,点击即可查看效果。
欢迎star。