Files
shoot-miniprograms/src/components/SModal.vue

83 lines
1.6 KiB
Vue
Raw Normal View History

2025-05-16 15:56:54 +08:00
<script setup>
import { ref, watch } from "vue";
const props = defineProps({
show: {
type: Boolean,
default: false,
},
onClose: {
type: Function,
default: () => {},
},
});
const showContent = ref(false);
watch(
() => props.show,
(newValue) => {
setTimeout(() => {
showContent.value = newValue;
}, 100);
}
);
const closeModal = () => {
showContent.value = false;
setTimeout(() => {
props.onClose();
}, 300);
};
</script>
<template>
<view class="container" v-if="show" :style="{ opacity: show ? 1 : 0 }">
<view
class="modal-content"
:style="{ transform: `translateY(${showContent ? '0%' : '100%'})` }"
>
<image src="../static/modal-content-bg.png" mode="widthFix" />
<view class="close-btn" @click="closeModal">
<image src="../static/close-yellow.png" mode="widthFix" />
</view>
<slot></slot>
</view>
</view>
</template>
<style scoped>
.container {
position: fixed;
top: 0;
left: 0;
background-color: #00000099;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
opacity: 0;
transition: all 0.3s ease;
}
.modal-content {
width: 100%;
height: 260px;
transform: translateY(100%);
transition: all 0.3s ease;
position: relative;
}
.modal-content > image:first-child {
width: 100%;
position: absolute;
z-index: -1;
}
.close-btn {
display: flex;
justify-content: flex-end;
position: absolute;
right: 0;
}
.close-btn > image {
width: 40px;
height: 40px;
}
</style>