<template>
<view>
<view v-if="visible" class="popup-mask" @click="hidePopup">
<view
class="popup-content"
:style="popupStyle"
:animation="animationData"
@click.stop
>
<slot></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'SlideDownPopup',
props: {
visible: {
type: Boolean,
default: false
},
height: {
type: String,
default: '30%'
}
},
data() {
return {
animationData: {},
popupStyle: {
transform: 'translateY(-100%)',
height: this.height
}
};
},
watch: {
visible(newVal) {
if (newVal) {
this.showPopup();
} else {
this.hidePopup();
}
}
},
methods: {
showPopup() {
this.$nextTick(() => {
const animation = uni.createAnimation({
duration: 300,
timingFunction: 'ease-out'
});
animation.translateY(0).step();
this.animationData = animation.export();
});
},
hidePopup() {
const animation = uni.createAnimation({
duration: 300,
timingFunction: 'ease-in'
});
animation.translateY('-100%').step();
this.animationData = animation.export();
setTimeout(() => {
this.$emit('update:visible', false);
this.popupStyle.transform = 'translateY(-100%)';
}, 300);
}
}
};
</script>
<style scoped>
.popup-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 999;
}
.popup-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: white;
z-index: 1000;
}
</style>
下面是使用得
<template>
<view>
<button @click="showPopup">Show Popup</button>
<SlideDownPopup :visible.sync="showFirstCategory" height="40%">
<!-- 这里是插槽内容 -->
<view style="padding: 20px;">
<text>这是弹出框的内容</text>
</view>
</SlideDownPopup>
</view>
</template>
<script>
import SlideDownPopup from './demo2.vue';
export default {
components: {
SlideDownPopup
},
data() {
return {
showFirstCategory: false
};
},
methods: {
showPopup() {
this.showFirstCategory = true;
}
}
};
</script>