简介:如果一个系统有很多需要弹框的业务,这么封装组件将非常实用。
封装一个基于ElementPlus的公共组件Dialog,拿去可以直接用。
这个组件封装了两个自定义事件 onClose关闭弹窗 onConfirm提交弹窗
宽,高,显示隐藏,标题都可以通过组件之间的通信来动态传递
ElementPlus的样式封装的太难改了。我就用 :global() 这个选择器,强制修改了。
被该选择器选中的类名将被视为全局的,不会受 CSS Modules 或其他局部作用域限制。
1、组件封装
<!--封装 公共弹窗 -->
<template>
<div>
<el-dialog :model-value="props.visible" :title="props.title" draggable="true"
:style="{ height: props.height + 'px', width: props.width + 'px' }" :before-close="onClose" append-to-body
:close-on-click-modal="false">
<span>
<!-- 定义插槽 可以动态传入内容 -->
<div class="mes">
<slot name="content"></slot>
</div>
</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="onClose">取消</el-button>
<el-button type="primary" @click="onConfirm">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { defineEmits} from "vue";
//数据类型
interface DialogProos {
title: string;//标题 必须参数
visible: boolean;//显示隐藏 必须参数
width?: number;//宽度
height?: number//高度
}
/* withDefaults() 函数接收两个对象作为参数:第一个是用户提供的选项,第二个是默认选项。
将这两个对象合并,确保用户提供的选项优先级高于默认选项。 */
const props = withDefaults(defineProps<DialogProos>(), {
title: "新增",
visible: false,
width: 400,
height: 450,
});
//自定义事件
const emit = defineEmits(["onClose", "onConfirm"]);
// 关闭||取消弹窗
const onClose = () => emit("onClose");
//确认弹窗
const onConfirm = () => emit("onConfirm");
</script>
<style lang="scss" scoped>
:global(.el-dialog__footer) {
position: absolute;
bottom: 10px;
right: 10px;
}
:global(.el-dialog__header) {
padding: 10px 15px;
background-color: #545c64;
}
:global(.el-dialog__title) {
color: #ffffff;
}
:global(.el-dialog) {
padding: 0;
}
.mes {
width: 70%;
margin-top: 30px;
display: flex;
}
</style>
2、封装工具类,不管那个组件只要调一下就行
import { reactive } from "vue";
export default function useDialog() {
//定义一个一般就是新增和编辑 自己看着加
const Title = {
ADD: "新增",
EDIT: "编辑",
};
//定义弹框标题
const dialog = reactive({
title:Title.ADD,//默认标题
visible: false,//默认是隐藏
width: 450,//默认宽度
height: 450,//默认高度
});
//弹窗的确认按钮提交
const onConfirm = () => (dialog.visible = false);
//弹窗的关闭
const onClose = () => (dialog.visible = false);
//弹窗的显示
const onShow = () => (dialog.visible = true);
return {
onClose,
onConfirm,
onShow,
Title,
dialog,
};
}
3、具体用法
(1)先引入公共组件和工具类,我这里组件是叫Dialig,工具类是useDialog;命名和存放路径是自定义的。
<script setup lang="ts">
import Dialog from '../../../components/Dialog/Dialog .vue';
import useDialog from '../../../utils/useDialog';
//把工具类里面的默认方法和对象引入
const {
onClose,
onShow,
dialog,
Title } = useDialog();
</script>
(2)使用该组件
<template>
<Dialog :title="dialog.title" :visible="dialog.visible"
:height="dialog.height" :width="dialog.width"
@on-close="onClose" @on-confirm="commit">
<template v-slot:content>
<!-- 自定义内容区 -->
</template>
</Dialog>
<el-button type="primary" @click="addBtn" icon="plus">新增</el-button>
<el-button size="small" icon="Edit" type="warning" @click="EditBtn">
</template>
(3)如果你不想用工具类里面定义好的默认函数,你可以向上面这个例子一样,我重新绑定了一个提交函数commit,里面可以写自己的逻辑。
想关闭弹框直接调onClose,想显示直接调onShow。
宽度,高度,标题,想变随时都能根据不同的业务需求而变动,里面的弹框内容也可以自定义,
非常灵活的一个弹框组件。
//提交
const commit = () => {
//这里可以写你自己的逻辑
}
const addBtn=()=>{
//并把弹框标题设置为新增,不喜欢的话还可以写字符串自定义
dialog.title=Title.ADD;
//这里只要调用一下,弹框就会显示
onShow();
}
const EditBtn=()=>{
//并把弹框标题设置为编辑,不喜欢的话还可以写字符串自定义
dialog.title=Title.EDIT;
//这里只要调用一下,弹框就会显示
onShow();
}