初始化本地仓库
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<component
|
||||
:is="dialogComponent"
|
||||
:class="customClass"
|
||||
:destroy-on-close="dialogPropsRef.destroyOnClose ?? true"
|
||||
:close-on-click-modal="dialogPropsRef.closeOnClickModal ?? false"
|
||||
:close-on-press-escape="dialogPropsRef.closeOnPressEscape ?? true"
|
||||
v-model="dialogVisible"
|
||||
:width="dialogPropsRef.width ?? '60%'"
|
||||
:title="dialogPropsRef.title ?? '操作'"
|
||||
:fullscreen="fullscreen"
|
||||
:show-close="dialogPropsRef.showClose ?? true"
|
||||
:direction="dialogPropsRef.direction ?? 'rtl'"
|
||||
:size="dialogPropsRef.width ?? '40%'"
|
||||
:modal="dialogPropsRef.modal ?? true"
|
||||
:append-to-body="true"
|
||||
:draggable="dialogPropsRef.draggable ?? true"
|
||||
>
|
||||
<template #header="{ close, titleId, titleClass }">
|
||||
<div class="el-dialog__header-inner">
|
||||
<span :id="titleId" :class="titleClass">{{ dialogPropsRef.title ?? '操作' }}</span>
|
||||
<div class="dialog-header-actions">
|
||||
<ElButton
|
||||
v-if="dialogPropsRef.dialogType === 'dialog'"
|
||||
class="dialog-header-btn"
|
||||
@click="toggleFullscreen"
|
||||
link
|
||||
>
|
||||
<template #icon>
|
||||
<Icon :icon="fullscreen ? 'ri:fullscreen-exit-line' : 'ri:fullscreen-line'" />
|
||||
</template>
|
||||
</ElButton>
|
||||
<ElButton class="dialog-header-btn" @click="close" link>
|
||||
<Icon icon="ri:close-large-line" />
|
||||
</ElButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="m-dialog-body" v-loading="dialogPropsRef.loading ?? false">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<template #footer v-if="dialogPropsRef.footer">
|
||||
<slot name="footer">
|
||||
<slot name="prepend-footer"></slot>
|
||||
<div class="footer-right">
|
||||
<ElButton v-if="dialogPropsRef.showCancelButton" @click="handleCancel">取消</ElButton>
|
||||
<slot name="center-footer"></slot>
|
||||
<ElButton
|
||||
v-if="dialogPropsRef.showConfirmButton"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
v-loading="dialogPropsRef.confirmLoading ?? false"
|
||||
>确定</ElButton
|
||||
>
|
||||
</div>
|
||||
<slot name="append-footer"></slot>
|
||||
</slot>
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Icon } from '@/components/icon'
|
||||
import { DialogEmits, MyDialogInstance, MyDialogProps } from './types'
|
||||
import { ElDialog, ElDrawer } from 'element-plus'
|
||||
|
||||
const props = withDefaults(defineProps<MyDialogProps>(), {
|
||||
loading: false,
|
||||
confirmLoading: false,
|
||||
showConfirmButton: true,
|
||||
showCancelButton: true,
|
||||
footer: true,
|
||||
dialogType: 'dialog',
|
||||
draggable: false
|
||||
})
|
||||
|
||||
const emit = defineEmits<DialogEmits>()
|
||||
const dialogVisible = ref(false)
|
||||
const fullscreen = ref(false)
|
||||
|
||||
// 根据 dialogType 决定使用哪个组件
|
||||
const dialogComponent = computed(() => {
|
||||
return dialogPropsRef.value.dialogType === 'drawer' ? ElDrawer : ElDialog
|
||||
})
|
||||
|
||||
// 根据 dialogType 设置不同的 customClass
|
||||
const customClass = computed(() => {
|
||||
const baseClass = dialogPropsRef.value.customClass ?? 'm-dialog'
|
||||
return dialogPropsRef.value.dialogType === 'drawer'
|
||||
? `${baseClass} m-drawer`
|
||||
: `${baseClass} m-dialog-box`
|
||||
})
|
||||
|
||||
const dialogPropsRef = ref<MyDialogProps>(props)
|
||||
const toggleFullscreen = () => {
|
||||
fullscreen.value = !fullscreen.value
|
||||
}
|
||||
const handleCancel = () => {
|
||||
dialogVisible.value = false
|
||||
if (props.onCancel) {
|
||||
props.onCancel()
|
||||
} else {
|
||||
emit('cancel')
|
||||
}
|
||||
}
|
||||
const handleSubmit = () => {
|
||||
if (props.onConfirm) {
|
||||
props.onConfirm()
|
||||
} else {
|
||||
emit('confirm')
|
||||
}
|
||||
}
|
||||
const methods: MyDialogInstance = {
|
||||
open() {
|
||||
dialogVisible.value = true
|
||||
},
|
||||
close() {
|
||||
dialogVisible.value = false
|
||||
},
|
||||
// 设置组件状态(props)
|
||||
setState(state: MyDialogProps) {
|
||||
return new Promise((resolve) => {
|
||||
dialogPropsRef.value = {
|
||||
...dialogPropsRef.value,
|
||||
...state
|
||||
}
|
||||
nextTick(() => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
getState(): Promise<MyDialogProps> {
|
||||
return new Promise((resolve) => {
|
||||
resolve(dialogPropsRef.value)
|
||||
})
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
emit('register', methods)
|
||||
})
|
||||
defineExpose(methods)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-dialog__header-inner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dialog-header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dialog-header-btn {
|
||||
margin-left: 10px;
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
:deep(.el-icon) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
:deep(.el-dialog__header) {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
:deep(.el-drawer__header) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
// 全局样式,用于区分 dialog 和 drawer 的外观
|
||||
.m-dialog-box {
|
||||
padding: 0;
|
||||
|
||||
.el-dialog__header {
|
||||
// background-color: var(--el-color-primary-light-6);
|
||||
// border-bottom: 1px solid var(--el-border-color);
|
||||
padding: 15px 20px !important;
|
||||
}
|
||||
|
||||
.m-dialog-body {
|
||||
background-color: var(--el-bg-color);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
// background-color: var(--el-color-primary-light-6);
|
||||
border-top: 1px solid var(--el-border-color);
|
||||
padding: 15px 20px !important;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
.el-dialog__body {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.m-drawer {
|
||||
.el-drawer__header {
|
||||
// background-color: var(--el-color-primary-light-6);
|
||||
// border-bottom: 1px solid var(--el-border-color);
|
||||
padding: 15px 20px !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.m-dialog-body {
|
||||
background-color: var(--el-bg-color);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.el-drawer__footer {
|
||||
// background-color: var(--el-color-primary-light-6);
|
||||
border-top: 1px solid var(--el-border-color);
|
||||
padding: 15px 20px !important;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
.el-drawer__body {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 底部按钮两端对齐的样式(用于select-dept和select-position组件)
|
||||
.m-dialog-footer-between {
|
||||
.el-dialog__footer {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.el-drawer__footer {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user