Vue3封装全局弹窗组件(结合el-dialog)
在main.ts中import App from "./App.vue";import SubDialog from '@/components/sub.js'let instance: any = null;instance = createApp(App)instance.use(SubDialog)instance.mount(document.getElementById("app")}在
·
在main.ts中
import App from "./App.vue";
import SubDialog from '@/components/sub.js'
let instance: any = null;
instance = createApp(App)
instance.use(SubDialog)
instance.mount(document.getElementById("app")}
在components下的sub.js
import SubDialog from './SubDialog.vue'
import { createApp } from 'vue'
let mountNode
let createMount = (opts) => {
if(mountNode){//确保只存在一个弹框
document.body.removeChild(mountNode)
mountNode = null
}
mountNode = document.createElement('div')
document.body.appendChild(mountNode)
const app = createApp(SubDialog, {
...opts,
modelValue: true,
remove() { //传入remove函数,组件内可移除dom 组件内通过props接收
app.unmount(mountNode)
document.body.removeChild(mountNode)
}
})
return app.mount(mountNode)
}
function V3Popup(options = {}) {
options.id = options.id || 'v3popup_' + 1 //唯一id 删除组件时用于定位
let $inst = createMount(options)
return $inst
}
V3Popup.install = app => {
app.component('v3-popup', SubDialog)
app.config.globalProperties.$subDialog = V3Popup
// app.provide('subDialog', V3Popup)
}
export default V3Popup
components下的SubDialog.vue
<template>
<!-- 封装弹框 -->
<div>
<el-dialog
custom-class="subDialog"
:title="dialogTitle"
v-model="dialogPopVisible"
:width="popupWidth"
:before-close="onBeforeClose"
:center="true"
>
<div>输入内容</div>
<template #footer class="dialog-footer">
footer
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, computed, defineProps } from "vue";
const props = defineProps({
title: {
type: String,
default: "",
},
width: {
type: String,
default: "550px",
},
option: {
type: Object,
default: {
//可传递其他值
},
},
cancelClick: {
type: Function,
default: () => {},
},
saveClick: {
type: Function,
default: () => {},
},
});
const dialogPopVisible = ref(true); // 窗体显示控制
const popupWidth = computed(() => {
return props.width || "550px";
});
const dialogTitle = computed(() => {
return props.title || "标题";
});
const Cancel = () => {
dialogPopVisible.value = false;
props.cancelClick();
};
const Save = () => {
dialogPopVisible.value = false;
props.saveClick('传值');
};
const onBeforeClose = (done) => {
done();
};
</script>
<style lang="scss">
.subDialog {
&.el-dialog {
z-index: 99;
background-color: #ffffff;
margin-top: 20% !important;
}
.el-dialog__header {
width: 100%;
height: 50px;
line-height: 50px;
box-sizing: border-box;
padding: 0 25px;
text-align: left;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.el-dialog__headerbtn {
font-size: 20px;
width: 40px;
height: 40px;
}
.el-dialog__title {
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
}
.el-dialog__body {
box-sizing: border-box;
padding: 20px 25px;
}
.el-dialog__footer {
text-align: right;
height: 60px;
line-height: 60px;
padding: 0;
margin-right: 20px;
border-top: 1px solid rgba(0, 0, 0, 0.06);
}
}
</style>
.vue中使用
const { proxy }: any = getCurrentInstance();
proxy.$subDialog({
title: "title",
width: "550px",
option: {
},
cancelClick: () => {},
saveClick: async (val) => {
console.log(val)
},
});
更多推荐
已为社区贡献3条内容
所有评论(0)