封装dialog弹窗
Vue3 + ts函数式封装
演示
代码说明
vue文件使用代码
js
// ======= 依赖引入 =======
import { getCurrentInstance } from 'vue'
// ======= 变量声明 =======
const { proxy }: any = getCurrentInstance()
// ======= 函数声明 =======
function showDialog() {
// 使用全局封装的弹窗
proxy.$dialog().then(res => {
// 确定事件
}).catch(err => {
// 取消事件
})
}
函数封装: 源代码
ts
import { ref, createApp } from 'vue'
// @ts-ignore
import dialogModule from './dialogModule.vue'
interface OptionsType {
title?: string // 标题
mainText?: string // 内容
width?: string // 宽度
LeftText?: string // 左侧按钮文字
LeftType?: string // 左侧按钮样式,支持elementUI组件库按钮组type
RightText?: string // 右侧按钮文字
RightType?: string // 右侧按钮样式,支持elementUI组件库按钮组type
}
const visible = ref(false)
export default function (options: OptionsType = {}) {
return new Promise((resolve, reject) => {
// 创建dom实例挂载在body上边
const div = document.createElement('div')
div.style.width = '0'
div.style.height = '0'
document.body.appendChild(div)
const module = createApp(dialogModule, {
modelValue: visible,
resolve: () => {
resolve('成功返回')
div.remove()
},
reject: () => {
reject('失败返回')
div.remove()
},
...options
})
module.mount(div)
visible.value = true
})
}
vue组件封装
源代码
vue
<template>
<a-modal v-model:open="visible" wrapClassName="dialog-box" :width="width" :closable="false" :footer="null" @cancel="closeVisible">
<div @click="closeVisible" class="jw-dialog-close">×</div>
<template #header>
<div>{{ title }}</div>
</template>
<div class="jw-dialog-cont">
<div>{{ mainText }}</div>
</div>
<div class="jw-dialog-btn">
<a-button :type="LeftType" @click="closeVisible">{{ LeftText }}</a-button>
<a-button :type="RightType" @click="submit">{{ RightText }}</a-button>
</div>
</a-modal>
</template>
<script setup lang="ts">
// ======= 依赖引入 =======
import { computed, watch } from 'vue'
// ======= 类型声明 =======
// ======= 变量声明 =======
const props = defineProps({
modelValue: {
type: Boolean,
required: true,
default: false
},
resolve: {
type: Function,
default: undefined
},
reject: {
type: Function,
default: undefined
},
title: {
type: String,
default: '标题'
},
mainText: {
type: String,
default: '弹窗内容'
},
width: {
type: String,
default: '400px'
},
LeftText: {
type: String,
default: '取消'
},
LeftType: {
type: [String, undefined],
default: undefined
},
RightText: {
type: String,
default: '确认'
},
RightType: {
type: [String, undefined],
default: 'primary'
}
})
const emits = defineEmits<{
(_e: 'update:modelValue', _v: boolean): void
}>()
const visible = computed<boolean>({
get() {
return props.modelValue
},
set(val: boolean) {
emits('update:modelValue', val)
}
})
watch(props, (val) => {
console.log(val.modelValue)
})
// ======= 主流程 =======
// ======= 函数声明 =======
// 关闭弹窗
function closeVisible() {
emits('update:modelValue', false)
props.reject!()
}
// 确认按钮
function submit() {
emits('update:modelValue', false)
props.resolve!()
}
// ======= 属性返回 =======
</script>
<style lang="scss" scoped>
.dialog-box {
.jw-dialog-cont {
margin-top: 20px;
}
.jw-dialog-close {
position: absolute;
top: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
width: 30px;
height: 30px;
padding: 10px;
box-sizing: border-box;
cursor: pointer;
}
// 底部按钮组
.jw-dialog-btn {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
.ant-btn {
margin-right: 12px;
&:last-child {
margin-right: 0;
}
}
}
</style>