| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- <template>
- <view
- v-if="show"
- class="zy-half-screen-dialog"
- :class="extClass"
- data-target="screen-dialog"
- @click="tapMask"
- >
- <view
- class="zy-half-screen-dialog-content"
- :style="{ height: height }"
- :data-visible="visible"
- :animation="contentAnimation"
- @transitionend="updateVisible"
- @click.stop=""
- >
- <slot></slot>
- </view>
- </view>
- </template>
- <script lang="ts" setup>
- import { nextTick, ref, watch } from 'vue';
- const props = defineProps({
- show: {
- type: Boolean,
- default: false,
- },
- height: {
- type: String,
- default: '80%',
- },
- extClass: {
- type: String,
- default: '',
- },
- });
- const maskClosable = ref(true);
- const duration = 300;
- const contentAnimation = ref(null);
- const visible = ref(false);
- const emits = defineEmits(['update:show']);
- const tapMask = (e) => {
- if (e.currentTarget.dataset.target !== 'screen-dialog') {
- return;
- }
- if (maskClosable.value) {
- close();
- }
- };
- const updateVisible = (e) => {
- const { visible } = e.currentTarget.dataset;
- nextTick(() => {
- if (!visible) {
- emits('update:show', visible);
- }
- });
- };
- const open = () => {
- const up = uni.createAnimation({
- duration,
- });
- up.translateY(0).step();
- contentAnimation.value = up.export();
- visible.value = true;
- };
- const close = () => {
- const down = uni.createAnimation({
- duration,
- });
- down.translateY('120%').step();
- contentAnimation.value = down.export();
- visible.value = false;
- };
- watch(
- () => props.show,
- (v) => {
- visible.value = v;
- if (v) {
- nextTick(() => open());
- } else {
- nextTick(() => close());
- }
- }
- );
- </script>
- <style lang="scss" scoped>
- .zy-half-screen-dialog {
- height: 100%;
- width: 100%;
- background-color: #00000083;
- position: fixed;
- top: 0;
- left: 0;
- z-index: 999999;
- }
- .zy-half-screen-dialog-content {
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- background-color: #ffffff;
- border-top-left-radius: 30rpx;
- border-top-right-radius: 30rpx;
- overflow: hidden;
- min-height: 20%;
- height: 80%;
- transform: translateY('100%');
- }
- </style>
|