场景
2023年09月21日
一、Modal
- App.vue
- Modal.vue
<template>
<button @click="handleShowModel(true)">显示 Model</button>
<Teleport to="body">
<Modal :show="isShowModel" @setShow="handleShowModel">
<template #header>
<h3>Modal 标题</h3>
</template>
</Modal>
</Teleport>
</template>
<script setup>
import { ref } from 'vue';
import Modal from './components/Modal.vue';
const isShowModel = ref(false);
const handleShowModel = value => {
isShowModel.value = value;
};
</script>
<template>
<Transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
<h3>modal-header</h3>
</slot>
</div>
<div class="modal-body">
<slot name="body">modal-body</slot>
</div>
<div class="modal-footer">
<slot name="footer">
<button class="modal-defalut-button" @click="handleCancel">
取消
</button>
<button class="modal-defalut-button" @click="handleConfirm">
确认
</button>
</slot>
</div>
</div>
</div>
</Transition>
</template>
<script setup>
const props = defineProps({
show: Boolean
});
const emits = defineEmits(['setShow']);
const handleCancel = () => {
emits('setShow', false);
};
const handleConfirm = () => {
emits('setShow', false);
};
</script>
<style scoped>
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
transition: opacity 0.3s ease;
}
.modal-container {
width: 300px;
margin: auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
transition: all 0.3s ease;
}
.modal-header h3 {
margin-top: 0;
color: #42b983;
}
.modal-body {
margin: 20px 0;
}
.modal-default-button {
float: right;
}
/*
* transition name="modal" 过渡
* .modal-enter-from
* .modal-leave-to
*/
.modal-enter-from {
opacity: 0;
}
.modal-leave-to {
opacity: 0;
}
.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>