实现效果:
组件代码:注意 style 不能为 scoped
TypeScript
<template>
<el-dialog class="my-dialog" v-model="isVisible" :show-close="false" :close-on-click-modal="false" :modal="false"
modal-class="my-modal-class" :draggable="props.draggable">
<template #header>
<div class="my-header">
{{ props.title }}
<div style="cursor: pointer" @click="handleClose">
<el-icon>
<CloseBold/>
</el-icon>
</div>
</div>
</template>
<div class="my-content">
<slot name="content"/>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import {ref} from "vue";
import {CloseBold} from "@element-plus/icons-vue";
const props = defineProps<{
isVisible: boolean, // 是否显示
title: string, // 标题
draggable: boolean // 是否拖动
}>()
const isVisible = ref(props.isVisible)
const handleClose = () => {
isVisible.value = false
}
</script>
<style lang="scss">
.my-dialog {
pointer-events: auto; // 确保弹窗内的点击事件生效
width: 400px;
margin: 0;
padding: 0;
background: none;
position: absolute;
top: 300px;
left: 500px;
.el-dialog__header {
padding-bottom: 0;
.my-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 30px;
background: rgba(89, 123, 244);
color: #FFFFFF;
}
}
.my-content {
background: #FFFFFF;
padding: 15px 30px;
font-size: 16px;
}
}
.my-modal-class {
pointer-events: none; // 保证遮罩下的区域点击事件生效
}
</style>
使用:v-bind 同时绑定多个属性
TypeScript
<template>
<custom-dialog v-bind="myDialog">
<template #content>自定义内容</template>
</custom-dialog>
</template>
<script setup lang="ts">
import CustomDialog from '@/components/CustomDialog/index.vue'
import {onMounted, ref} from "vue";
const myDialog = ref({
isVisible: true,
title: '二次封装el-dialog',
draggable: true
})
</script>