VUE3 封装 element-plus中的 dialog 组件
element
A Vue.js 2.0 UI Toolkit for Web
项目地址:https://gitcode.com/gh_mirrors/eleme/element
免费下载资源
·
一、封装原因
因为我在开发中不想使用 el-dialog 直接写页面,我想向下面这样使用组件,这样包括弹框头部、内容、底部都可以以组件形式传入插件实现分离控制
DialogBox({
title: item.name == 'qq' ? 'QQ名片' : '微信名片',
dom: QqCode,
option: {
type: item.name
}
})
二、具体代码如下
主内容文件----index.vue
<template>
<el-dialog
class="dialog-plus"
modal-class="dialog-plus-modal"
:modal="props.modal"
:close-on-click-modal="props.closeOnClickModal"
align-center
v-model="visible"
:width="props.width"
:show-close="false"
@close="dealClose"
@closed="dealClosed"
>
<div class="dialog-content">
<component
:is="props.dom"
v-bind="props.option"
v-on="{
...props.events,
close: closeDialog
}"
/>
</div>
<template #header>
<div class="dialog-header">
<div class="dialog-title">
<component
v-if="headerDom"
:is="props.headerDom"
v-bind="props.headerOption"
v-on="{
...props.headerEvents,
close: closeDialog
}"
/>
<template v-else>{{ props.title }}</template>
</div>
<i-ep-close class="dialog-close" @click="closeDialog" />
</div>
</template>
<template #footer v-if="showFooter">
<component
v-if="footerDom"
:is="props.footerDom"
v-bind="props.footerOption"
v-on="{
...props.footerEvents,
close: closeDialog
}"
/>
<div v-else class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="dealConfirm"> 确认 </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
defineOptions({
name: 'DialogPlus'
})
const props = defineProps({
title: {
type: String,
default: '标题'
},
width: {
type: [Number, String],
default: 500
},
modal: {
type: Boolean,
default: true
},
closeOnClickModal: {
type: Boolean,
default: true
},
dom: {
type: Object,
default: null
},
option: {
type: Object,
default: () => ({})
},
events: {
type: Object,
default: () => ({})
},
headerDom: {
type: Object,
default: null
},
headerOption: {
type: Object,
default: () => ({})
},
headerEvents: {
type: Object,
default: () => ({})
},
showFooter: {
type: Boolean,
default: false
},
footerDom: {
type: Object,
default: null
},
footerOption: {
type: Object,
default: () => ({})
},
footerEvents: {
type: Object,
default: () => ({})
},
immediately: {
type: Boolean,
default: true
},
close: {
type: Function,
default: null
},
closed: {
type: Function,
default: null
},
confirm: {
type: Function,
default: null
}
})
const visible = ref(false)
onMounted(() => {
visible.value = true
})
const closeDialog = () => {
visible.value = false
}
const dealClose = () => {
props.close && props.close()
}
const dealClosed = () => {
props.closed && props.closed()
}
const dealConfirm = () => {
if (!props.confirm) return
if (props.immediately) {
visible.value = false
props.confirm()
} else {
props.confirm(() => {
visible.value = false
})
}
}
</script>
<style lang="scss">
.dialog-plus {
margin: auto !important;
min-height: 500px;
height: fit-content;
background: #03151fca;
border: 1px solid #2aa8ff;
box-shadow: 0px 1px 8px 0px #2aa8ff, inset 0px 1px 5px 0px #2aa8ff;
color: #fff;
padding: 10px;
.el-dialog__header {
position: relative;
box-sizing: border-box;
padding: 0 10px;
line-height: 50px;
height: 50px;
width: 100%;
background: linear-gradient(
45deg,
rgb(2 103 153 / 82%) 0%,
rgb(0 55 71 / 56%) 100%
);
border-radius: 2px;
.dialog-header {
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
.dialog-title {
font-size: 18px;
text-align: left;
}
.dialog-close {
font-size: 18px;
cursor: pointer;
transition: all 0.2s;
&:hover {
color: rgb(40, 205, 255);
}
}
}
.el-dialog__headerbtn {
top: 50%;
z-index: 10;
transform: translateY(-50%);
.el-dialog__close {
color: #fff;
font-size: 25px;
transition: all 0.2s;
}
&:hover {
.el-dialog__close {
color: rgb(40, 205, 255);
}
}
}
}
.el-dialog__body {
height: 100%;
padding: 0;
color: #fff;
.dialog-content {
padding: 10px 0;
}
}
.dialog-footer {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
}
</style>
实现函数式封装的方法文件 index.js
import { createApp } from 'vue'
import DialogPlus from './index.vue'
import { uniqueId } from 'lodash-es'
let instance = null
let instanceApp = null
let isExist = null
let isExistApp = null
const DialogBox = (data) => {
if (!data.dom) {
console.log('内容缺失')
return false
}
if (data.coexist) {
isExist = document.createElement('div')
isExist.setAttribute('id', uniqueId('dialog-'))
document.body.appendChild(isExist)
isExistApp = createApp(DialogPlus, {
...data,
closed: () => {
isExistApp.unmount()
isExist.remove()
data.closed && data.closed()
}
})
isExistApp.mount(isExist)
} else {
if (isExist) {
isExistApp.unmount()
isExist.remove()
}
if (instance) {
instanceApp.unmount()
instance.remove()
} // 移除已有弹窗,确保只有一个弹窗显示
instance = document.createElement('div')
instance.setAttribute('id', uniqueId('dialog-'))
document.body.appendChild(instance)
instanceApp = createApp(DialogPlus, {
...data,
closed: () => {
instanceApp.unmount()
instance.remove()
data.closed && data.closed()
}
})
instanceApp.mount(instance)
}
}
export default DialogBox
使用方法
DialogBox({
title: '123',
dom: QqCode,
option: {}
})
三、参数说明
参数 | 说明 | 备注 |
title | 标题 | |
width | 宽度 | |
modal | 是否要蒙层 | |
closeOnClickModal | 点击蒙层关闭弹窗 | |
dom | 内容组件(VUE 组件) | |
option | 传给内容组件的参数 | |
events | 绑定到内容组件的事件 | |
headerDom | 头部组件(VUE 组件) | 不传默认显示 title |
headerOption | 传给头部组件的参数 | |
headerEvents | 绑定到头部组件的事件 | |
showFooter | 是否有底部 | |
footerDom | 底部组件(VUE 组件) | 不传默认显示默认的底部组件 |
footerOption | 传给底部组件的参数 | |
footerEvents | 绑定到底部组件的事件 | |
immediately | 默认底部组件点击确认按钮是否立即关闭弹窗 | |
close | 关闭弹窗参数 | |
closed | 彻底关闭弹窗参数 | |
confirm | 确认关闭弹窗参数 |
效果如下图
GitHub 加速计划 / eleme / element
54.06 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:3 个月前 )
c345bb45
7 个月前
a07f3a59
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update table.md
* Update transition.md
* Update popover.md 7 个月前
更多推荐
已为社区贡献1条内容
所有评论(0)