You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
1.5 KiB
Vue

<template>
<!-- 遮罩层 -->
<view v-if="visible" class="popup-mask" @click="close">
<view @click.stop class="popup-content" :style="{ transform: transformStyle }">
<slot></slot>
</view>
</view>
</template>
<script setup>
import {
ref,
computed,
defineExpose
} from 'vue'
const props = defineProps({
position: {
type: String,
default: 'bottom'
},
duration: {
type: Number,
default: 300
}
})
const emit = defineEmits(['open', 'close'])
const visible = ref(false)
const animating = ref(false)
// 动画样式
const transformStyle = computed(() => {
if (animating.value) return 'translateY(0%)'
if (props.position === 'bottom') return 'translateY(100%)'
if (props.position === 'top') return 'translateY(-100%)'
return 'scale(0.8)'
})
// 对外暴露的方法
function open() {
visible.value = true
animating.value = false
setTimeout(() => {
animating.value = true
emit('open')
}, 20)
}
function close() {
animating.value = false
setTimeout(() => {
visible.value = false
emit('close')
}, props.duration)
}
defineExpose({
open,
close
})
</script>
<style>
.popup-mask {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: flex-end;
z-index: 999;
}
.popup-content {
width: 100%;
background: #fff;
border-radius: 16rpx 16rpx 0 0;
transition: transform 0.3s ease;
}
</style>