101 lines
2.1 KiB
Vue
101 lines
2.1 KiB
Vue
<template>
|
|
<view>
|
|
<uni-popup ref="popup" style="z-index: 9999;" :safe-area="false" type="bottom" change="change" @maskClick="change" background-color="#fff"
|
|
border-radius="15px 15px 0 0">
|
|
<view class="popup" :style="{ background: background }">
|
|
<view class="top-touch" @touchstart="touchStart" @touchend="touchEnd">
|
|
<view class="center">
|
|
<image v-if="props.backShow" src="https://6a69-jinxiangguo-7g6kqddnb0a8aa47-1326817332.tcb.qcloud.la/img/touch-close-black.png" mode="heightFix"></image>
|
|
</view>
|
|
</view>
|
|
<view class="content">
|
|
<slot></slot>
|
|
</view>
|
|
</view>
|
|
</uni-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import {
|
|
ref,
|
|
defineExpose,
|
|
defineProps,
|
|
getCurrentInstance
|
|
} from 'vue'
|
|
const {proxy} = getCurrentInstance()
|
|
|
|
const props = defineProps({
|
|
backShow: {
|
|
type: Boolean,
|
|
default: false
|
|
}, // 顶部小黑条是否显示
|
|
background: String
|
|
})
|
|
|
|
const popup = ref() // ref组件
|
|
let touchStartX = 0
|
|
let touchStartY = 0
|
|
|
|
const open = () => {
|
|
popup.value.open()
|
|
} // 自定义方法
|
|
const close = () => {
|
|
proxy.$emit('close')
|
|
popup.value.close()
|
|
}
|
|
const touchStart = (e) => {
|
|
touchStartX = e.touches[0].clientX
|
|
touchStartY = e.touches[0].clientY
|
|
}
|
|
const touchEnd = (e) => {
|
|
// console.log("触摸结束")
|
|
let deltaX = e.changedTouches[0].clientX - touchStartX;
|
|
let deltaY = e.changedTouches[0].clientY - touchStartY;
|
|
if (Math.abs(deltaY) > 50 && Math.abs(deltaX) < Math.abs(deltaY)) {
|
|
if (deltaY > 0) {
|
|
close()
|
|
}
|
|
}
|
|
}
|
|
const change = (e) => {
|
|
proxy.$emit('close')
|
|
}
|
|
defineExpose({
|
|
open,
|
|
close
|
|
}) // 暴露方法
|
|
</script>
|
|
|
|
<style scoped>
|
|
.content {
|
|
height: 85vh;
|
|
}
|
|
|
|
.popup {
|
|
overflow: hidden;
|
|
border-top-right-radius: 15px;
|
|
border-top-left-radius: 15px;
|
|
}
|
|
|
|
.top-touch {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 10px 0;
|
|
position: absolute;
|
|
width: 100%;
|
|
z-index: 9;
|
|
}
|
|
|
|
.top-touch image {
|
|
height: 5px;
|
|
}
|
|
.left,.right {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
</style> |