业务弹窗
js
<template>
<t-dialog v-model:visible="visible" :on-confirm="onConfirm" :on-close="onClose">
<template #body>
<!-- 添加业务逻辑 -->
</template>
</t-dialog>
</template>
<script setup lang="ts">
import { defineExpose, ref, defineProps } from 'vue';
interface DialogData {}; // 根据实际情况定义数据类型
interface Props {
confirm?: Function;
cancel?: Function;
// 可以根据实际情况在配置其他参数
};
const props = defineProps<Props>();
const visible = ref(false);
const dialogData = ref<DialogData>();
const open = (data: DialogData) => {
// 外层传递进来的参数
dialogData.value = data;
// TODO 处理弹窗打开前的业务逻辑
visible.value = true;
}
// 确定
const onConfirm = () => {
// TODO 处理弹窗关闭前的业务逻辑
if (typeof props.confirm === 'function') {
props.confirm({
// 可以将数据传递给到外层
});
}
visible.value = false;
}
// 取消
const onClose = () => {
// TODO 处理弹窗里面的业务逻辑
if (typeof props.cancel === 'function') {
props.cancel({
// 可以将数据传递给到外层
});
}
visible.value = false;
}
defineExpose({
open // 必须把 open 抛出
});
</script>
关键点
- 弹窗组件需要抛出
open
方法。上层Hooks
会通过open
将数据传入到弹窗组件中。 - 弹窗组件内部可以根据实际业务要求,定义
confirm
或cancel
,将数据传到上层。
Hooks 统一处理弹窗
js
import { h, render } from 'vue';
// 将弹窗导入
import EditDialog from '@/components/dialog/editDialog.vue';
interface Props {
[key: string]: any;
confirm?: Function;
cancel?: Function;
}
// 渲染弹窗
export function createComponent(singleFileComponent: any, props?: any) {
let container: HTMLDivElement = null;
if (!container) {
container = document.createElement('div');
container.id = uuidv4();
}
const instance = h(singleFileComponent, props);
render(instance, container);
document.body.appendChild(container);
const { exposed } = instance.component;
return exposed;
}
// 将数据传入到弹窗中
const createDialog = (singleFileComponent: any) => {
return (data? any; props?: Props) => {
// 将上层传递的参数(props)传入,并返回业务弹窗组件实例
const exposed = createComponent(singleFileComponent, props);
// 调用 open
exposed.open(data);
}
}
// 初始化弹窗
const initEditDialog = createDialog(EditDialog);
export const useDialog = () => {
return {
initEditDialog
}
}
使用弹窗
js
<template>
<div>
<t-button @click="showDialog">显示弹窗</t-button>
</div>
</template>
<script setup lang="ts">
import { useDialog } from '@/hooks/useDialog';
const { initEditDialog } = useDialog();
const showDialog = () => {
initEditDialog({
key1: '外层向弹窗传递的参数'
}, {
confirm: (data: any) => {
console.log('弹窗向外层传递的参数')
}
})
}
</script>