123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- <!-- BottomPopup.vue -->
- <template>
- <!-- 最外层用 transition 做遮罩的淡入淡出 -->
- <transition :name="overlayTransitionName">
- <!-- 遮罩 -->
- <div
- v-show="visible"
- class="overlay-mask"
- :class="overlayClass"
- @click.self="clickOverlay"
- >
- <!-- 内容区用另一个 transition 实现从底部滑出 -->
- <transition :name="contentTransitionName">
- <div v-show="visible" class="overlay-content" :class="overlayClass">
- <!-- 可定制的区域 -->
- <slot />
- </div>
- </transition>
- </div>
- </transition>
- </template>
- <script>
- export default {
- name: 'CommonDialog',
- props: {
- // 受控显示/隐藏
- visible: {
- type: Boolean,
- default: false
- },
- overlayTransitionName: {
- type: String,
- default: 'fade', // fade/slide-up
- },
- contentTransitionName: {
- type: String,
- default: '',
- },
- contentContainerClass: {
- type: String,
- default: ''
- },
- contentClass: {
- type: String,
- default: ''
- },
- overlayClass: {
- type: String,
- default: ''
- },
- },
- watch: {
- // 简单处理 body 滚动
- visible(val) {
- if (val) {
- document.body.style.overflow = 'hidden'
- }
- else {
- document.body.style.overflow = ''
- }
- }
- },
- methods: {
- clickOverlay() {
- this.syncVisible(false)
- },
- syncVisible(f = false) {
- this.$emit('update:visible', f)
- },
- }
- }
- </script>
- <style scoped lang="scss">
- /* 遮罩 */
- .overlay-mask {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.5);
- z-index: 999;
- }
- /* 遮罩淡入淡出 */
- .fade-enter-active,
- .fade-leave-active {
- transition: opacity 0.3s;
- }
- .fade-enter,
- .fade-leave-to {
- opacity: 0;
- }
- /* 内容从底部滑出 */
- .slide-up-enter-active,
- .slide-up-leave-active {
- transition: transform 0.3s ease-out;
- }
- .slide-up-enter,
- .slide-up-leave-to {
- transform: translate3d(0, 100%, 0);
- }
- </style>
|