初始提交:实习工作日志系统(设计方案 + Vue3 应用 + Electron 打包)
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import { onUnmounted, watch } from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
open: boolean
|
||||
title: string
|
||||
message: string
|
||||
confirmText?: string
|
||||
cancelText?: string
|
||||
danger?: boolean
|
||||
}>(), { confirmText: '确认', cancelText: '取消', danger: false })
|
||||
|
||||
const emit = defineEmits<{ (e: 'cancel'): void; (e: 'confirm'): void }>()
|
||||
|
||||
function onKey(e: KeyboardEvent) {
|
||||
if (!props.open) return
|
||||
if (e.key === 'Escape') emit('cancel')
|
||||
}
|
||||
watch(() => props.open, v => {
|
||||
if (v) window.addEventListener('keydown', onKey)
|
||||
else window.removeEventListener('keydown', onKey)
|
||||
})
|
||||
onUnmounted(() => window.removeEventListener('keydown', onKey))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<teleport to="body">
|
||||
<transition name="modal">
|
||||
<div v-if="open" class="mask" @click.self="emit('cancel')">
|
||||
<div class="dialog" role="dialog" :aria-label="title">
|
||||
<div class="dialog-title">{{ title }}</div>
|
||||
<div class="dialog-msg">{{ message }}</div>
|
||||
<div class="dialog-btns">
|
||||
<button class="btn btn-sm" @click="emit('cancel')">{{ cancelText }}</button>
|
||||
<button class="btn btn-sm" :class="danger ? 'btn-danger-solid' : 'btn-primary'" @click="emit('confirm')">{{ confirmText }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.mask {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(29, 33, 41, 0.4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 100;
|
||||
}
|
||||
.dialog {
|
||||
width: 380px;
|
||||
max-width: calc(100vw - 32px);
|
||||
background: var(--bg-page);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-float);
|
||||
padding: 20px;
|
||||
}
|
||||
.dialog-title { font-size: 14px; font-weight: 600; color: var(--text-1); }
|
||||
.dialog-msg { margin-top: 8px; color: var(--text-2); font-size: 13px; line-height: 1.7; word-break: break-all; }
|
||||
.dialog-btns { margin-top: 20px; display: flex; justify-content: flex-end; gap: 8px; }
|
||||
.btn-danger-solid { background: var(--danger); border-color: var(--danger); color: #FFFFFF; }
|
||||
.btn-danger-solid:hover { background: #D13A3F; }
|
||||
|
||||
.modal-enter-active, .modal-leave-active { transition: opacity 0.15s ease; }
|
||||
.modal-enter-from, .modal-leave-to { opacity: 0; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user