chat-pc/src/components/common/customModal.vue

157 lines
3.6 KiB
Vue

<template>
<xNModal v-model:show="show" v-bind="$attrs">
<template #header>
<div class="custom-modal-header">
<div class="header-content">
<template v-if="$slots.header">
<slot name="header"></slot>
</template>
<template v-else>
{{ title }}
</template>
<div class="custom-close-btn" v-if="customCloseBtn">
<img src="@/assets/image/icon/close-btn-grey.png" alt="" @click="handleCloseModal" />
</div>
</div>
</div>
</template>
<slot name="content"></slot>
<template #footer v-if="actionBtns?.cancelBtn || actionBtns?.confirmBtn">
<div
class="custom-modal-btns"
:style="props?.customModalBtnsStyle ? props.customModalBtnsStyle : ''"
>
<customBtn
color="#C7C7C9"
style="width: 161px; height: 34px;"
@click="handleCancel"
v-if="actionBtns?.cancelBtn"
>{{ actionBtns?.cancelBtn?.text || '取消' }}</customBtn
>
<customBtn
color="#46299D"
style="width: 161px; height: 34px;"
@click="handleConfirm"
:disabled="actionBtns?.confirmBtn?.disabled"
:loading="state.confirmBtnLoading && actionBtns?.confirmBtn?.doLoading"
v-if="actionBtns?.confirmBtn"
>{{ actionBtns?.confirmBtn?.text || '确定' }}</customBtn
>
</div>
</template>
</xNModal>
</template>
<script setup>
import { reactive, computed } from 'vue'
import xNModal from '@/components/x-naive-ui/x-n-modal/index.vue'
import customBtn from '@/components/common/customBtn.vue'
const props = defineProps({
show: {
// 是否显示模态框
type: Boolean,
default: false
},
title: {
// 模态框标题
type: String,
default: ''
},
actionBtns: {
// 操作按钮
type: Object,
default: () => ({})
},
customCloseBtn: {
// 是否显示自定义关闭按钮
type: Boolean,
default: false
},
customModalBtnsStyle: {
// 自定义按钮样式
type: String,
default: ''
},
customCloseEvent: {
// 是否自定义关闭事件
type: Boolean,
default: false
}
})
const emit = defineEmits(['update:show', 'cancel', 'confirm', 'customCloseModal'])
const show = computed({
get: () => props.show,
set: (val) => emit('update:show', val)
})
const handleCancel = () => {
if (props.actionBtns?.cancelBtn?.hideModal) {
show.value = false
}
emit('cancel')
}
const handleConfirm = () => {
if (props.actionBtns?.confirmBtn?.doLoading) {
state.confirmBtnLoading = true
}
emit('confirm', closeLoading)
}
const closeLoading = () => {
state.confirmBtnLoading = false
}
const state = reactive({
confirmBtnLoading: false // 确定按钮loading
})
const handleCloseModal = () => {
if (props.customCloseEvent) {
emit('customCloseModal')
} else {
show.value = false
}
}
</script>
<style scoped lang="less">
.custom-modal-header {
border-bottom: 1px solid #e5e5e5;
margin: 0 12px;
.header-content {
padding: 0 0 15px;
text-align: center;
color: #1f2225;
font-size: 20px;
font-weight: 600;
line-height: 28px;
position: relative;
.custom-close-btn {
position: absolute;
right: 0;
top: 0;
cursor: pointer;
img {
width: 30px;
height: 30px;
}
}
}
}
.custom-modal-btns {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
padding: 0 0 50px;
}
</style>