命令式弹框
以 promise 回调方式使用的 <el-dialog>
弹框组件。将打开弹框组件当做是打开一个异步函数,并从中获取到返回值。
设计初衷
尽量避免使用过于复杂的方式调用弹框。尽可能最简单的方式包装组件,满足简单的业务即可。
实现表单业务的返回值
特别是为了满足弹框内表单的业务。比如说弹框负责完成表单数据交互,完成后返回已经新增或修改的数据。页面随即从返回的数据内做其他接口交互,或者是其他行为。
不再让父组件维护弹框组件的显隐状态
避免让父组件手动管理弹框组件的显示和隐藏。这种方式很麻烦,容易新建很多变量。
最小案例
- 必须要提供
异步
的onDialogClose
函数。该函数默认返回布尔值
,表示控制弹框是否关闭。 - 必须要获得弹框实例,使用内部的异步函数控制弹框是否打开,并从中获取到返回值。
最小案例
loading
底部插槽
使用底部插槽提供 reject
和 resolve
作用域插槽参数,实现弹框的关闭逻辑。你应该在弹框关闭函数 onDialogClose 内实现全部的弹框关闭逻辑,比如常见的表单校验逻辑。
自己封装弹框关闭按钮
loading
设置弹框属性
在 dialogProps
内设置 <el-dialog>
的属性即可。
设置弹框标题
loading
部分字段不允许填写且不生效
为了防止使用的时候不小心覆盖掉弹框组件的默认行为,有部分字段被屏蔽使用了。被禁用的,默认使用的字段如下:
ts
/**
* 命令式弹框不允许外部传递的 el-dialog 属性
* @description
* - modelValue 不允许外部来管控弹框组件的`显示`和`隐藏`状态
* - draggable 弹框固定就是可以拖拽的 避免外部组件覆写掉该配置
* - beforeClose 不允许弹框组件使用该配置 该配置默认被 `onDialogClose` 函数使用
*/
const notUseElDialogProps = <const>["modelValue", "draggable", "beforeClose"];
export default notUseElDialogProps;
表单弹框例子
以下例子演示了如何使用命令式弹框实现简单的表单业务。
详情
loading
二次封装的注意事项
vueuse 的 createTemplatePromise 的渲染逻辑是:必须要先执行内部的创建组件实例函数。
如果二次封装时,直接以本组件为根元素的话,会导致父组件永远无法获取到有效的组件实例。
你应该按照以下方式来二次封装本组件。
必须提供有意义的 dom 元素作为根标签
vue
<script lang="ts" setup>
import ComponentsDialogPromise from "components/dialog-promise/index.vue";
import { defineExpose, ref } from "vue";
const props = ref<DialogPromiseProps<{}>>({
async onDialogClose({ reject, resolve }) {
resolve({});
return true;
},
});
const dialogRef = useTemplateRef("dialog");
function open() {
dialogRef.value?.open();
}
defineExpose({
// 对外导出打开弹框函数
open,
});
</script>
<template>
<!-- 你必须要提供一个有意义的根dom元素 否则父级无法获得组件实例 -->
<section class="must-has-dom-root">
<ComponentsDialogPromise :="props" ref="dialog" />
</section>
</template>
<style lang="scss" scoped>
.must-has-dom-root {
}
</style>
实现原理
本组件本质上是对 vueuse 的 createTemplatePromise 工具做二次封装。