



组件
<template>
<view class="panel" v-touch:swipeup="swipeup" v-touch:swipedown="swipedown" :style="{ height: `${height}px` }" :class="{ search_radius: !isScroll }">
<view class="tapBoxTouchLine" v-if="showLine" @click.stop="clickSwipe">
<slot name="header">slot>
view>
<view class="panel_content" style="overflow: hidden;">
<scroll-view scroll-y="true" :style="{ height: `${height-80}px` }">
<slot>slot>
scroll-view>
view>
view>
template>
<script>
export default {
props: {
minHeight: {
type: Number,
default: 70
},
middleHeight: {
type: Number,
default: 600
},
maxHeight:{
type: Number,
default: 800
},
showLine: {
type: Boolean,
default: true
}
},
data() {
return {
maxHeight: 400,
height: 70,
lastY: 0,
isScroll: false,
swipeShow: false
};
},
created() {
const info = uni.getSystemInfoSync();
this.maxHeight = info.windowHeight;
console.log(this.maxHeight);
},
directives: {
touch: {
bind: function(el, binding, vnode) {
var touchType = binding.arg;
var timeOutEvent = 0;
var direction = '';
var startX, startY;
function GetSlideAngle(dx, dy) {
return (Math.atan2(dy, dx) * 180) / Math.PI;
}
function GetSlideDirection(startX, startY, endX, endY) {
var dy = startY - endY;
var dx = endX - startX;
var result = 0;
if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
return result;
}
var angle = GetSlideAngle(dx, dy);
if (angle >= -45 && angle < 45) {
result = 'swiperight';
} else if (angle >= 45 && angle < 135) {
result = 'swipeup';
} else if (angle >= -135 && angle < -45) {
result = 'swipedown';
} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
result = 'swipeleft';
}
return result;
}
el.addEventListener(
'touchstart',
function(ev) {
startX = ev.touches[0].pageX;
startY = ev.touches[0].pageY;
timeOutEvent = setTimeout(() => {
timeOutEvent = 0;
if (touchType === 'press') {
binding.value();
}
}, 500);
},
false
);
el.addEventListener('touchmove', function(ev) {
clearTimeout(timeOutEvent);
timeOutEvent = 0;
});
el.addEventListener(
'touchend',
function(ev) {
var endX, endY;
endX = ev.changedTouches[0].pageX;
endY = ev.changedTouches[0].pageY;
direction = GetSlideDirection(startX, startY, endX, endY);
clearTimeout(timeOutEvent);
switch (direction) {
case 0:
break;
case 'swipeup':
if (touchType === 'swipeup') {
binding.value();
}
break;
case 'swipedown':
if (touchType === 'swipedown') {
binding.value();
}
break;
case 'swipeleft':
if (touchType === 'swipeleft') {
binding.value();
}
break;
case 'swiperight':
if (touchType === 'swiperight') {
binding.value();
}
break;
default:
}
},
false
);
}
}
},
methods: {
swipeup() {
this.swipeShow = true
this.$emit('swipeClick',this.swipeShow)
if (this.height < this.middleHeight) {
this.height = this.middleHeight;
this.isScroll = false;
} else {
this.height = this.maxHeight;
this.isScroll = true;
}
},
swipedown() {
this.swipeShow = false
this.$emit('swipeClick',this.swipeShow)
if (this.height < this.middleHeight) {
this.height = this.middleHeight;
this.isScroll = false;
} else {
this.height = this.minHeight;
this.isScroll = false;
}
},
clickSwipe(){
if(this.height > this.minHeight){
this.swipedown()
}else{
this.swipeup()
}
}
}
};
script>
<style lang="scss">
.panel {
z-index: 999;
position: fixed;
bottom: 0;
width: 100vw;
background-color: #ffffff;
padding: 0 20rpx 30rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
transition-duration: 0.5s;
.search_wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
margin-bottom: 20rpx;
.search_content {
height: 74rpx;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #ebf0f3;
border-radius: 16rpx;
border: 1rpx solid #dfe4e7;
padding: 0 20rpx;
.search_content_input {
flex: 1;
display: flex;
justify-content: flex-start;
align-items: center;
.search_icon {
margin-right: 10rpx;
}
.search_text {
color: #595e5f;
font-size: 32rpx;
letter-spacing: 1.8rpx;
}
}
.search_suffix {
width: 48rpx;
height: 48rpx;
image {
width: 100%;
height: 100%;
}
}
}
}
.panel_content {
width: 100%;
height: 100%;
}
}
.search_radius {
border-radius: 50rpx 50rpx 0 0;
box-shadow: 0 -8rpx 30rpx rgba(109, 109, 109, 0.1);
}
style>
禁用页面下拉上拉回弹

使用
<template>
<view class="">
<slide-popup :minHeight="70" :middleHeight="600" :showLine="true" @swipeClick="swipeClick">
<view class="tapBoxTouchLine" slot="header">
<view class="line">view>
<view class="title">{{ markShow ? '返回趣味抽盒' : '获取更多游戏机会' }}view>
<view class="text-tw">任务中心view>
view>
<view class="mission-center">
<image src="../../static/carton-drawer/banner.png" mode="">image>
<view class="">
<view class="mission-board-li" v-for="item in missionList">
<view class="h3">{{ item.texth }}view>
<view class="task-list" v-for="i in item.taskList">
<image :src="i.url" mode="">image>
<view class="task-warp">
<view class="title">{{ i.title }}view>
<view class="ip-beans">
可获得
<text>{{ i.ipbeans }}text>
豆
view>
<view class="text">{{ i.text }}view>
view>
<button class="give-away-btn" @click="leftClick">去完成button>
view>
view>
view>
view>
slide-popup>
<view class="mark" v-show="markShow">view>
view>
template>
<script>
export default {
props: {
},
data() {
return {
markShow:false,
missionList: [
{
texth: '新手任务',
taskList: [
{
url: '../../static/carton-drawer/fx-icon.png',
text: '每日限制一次',
ipbeans: '300Ip',
title: '分享好友'
},
{
url: '../../static/carton-drawer/yq-icon.png',
text: '邀请开卡有礼',
ipbeans: '100Ip',
title: '不限次数'
}
]
},
{
texth: '进阶任务',
taskList: [
{
url: '../../static/carton-drawer/gw-icon.png',
text: '不限次数',
ipbeans: '100 Ip',
title: '购买商品'
}
]
}
]
};
},
watch:{
markShow(n){
this.markShow = n
}
},
methods: {
swipeClick(show) {
this.markShow = show;
},
toAchieve() {}
}
};
script>
<style lang="scss" scoped>
.tapBoxTouchLine {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
.line {
margin: 10rpx 0;
vertical-align: middle;
border-bottom: 16rpx solid #9f9f9f;
border-radius: 10rpx 10rpx 0 0;
width: 76rpx;
transform: scaleY(0.5);
}
.title {
color: #666666;
margin: 0;
font-size: 24rpx;
}
.text-tw {
width: 96vw;
margin-left: 2vw;
height: 60rpx;
line-height: 60rpx;
font-size: 28rpx;
color: #999999;
text-align: start;
}
}
.mission-center {
margin-top: 12rpx;
image {
width: 98%;
margin-left: 1%;
height: 212rpx;
border-radius: 40rpx;
}
.mission-board-li {
.h3 {
border-left: solid #f75348 8rpx;
padding-left: 30rpx;
border-radius: 8rpx;
font-size: 36rpx;
font-weight: 700;
margin: 40rpx 0;
}
.task-list {
display: flex;
justify-content: space-between;
align-items: center;
height: 160rpx;
image {
width: 76rpx;
height: 76rpx;
}
.task-warp {
width: 57%;
.title {
font-size: 32rpx;
font-weight: 700;
margin-bottom: 12rpx;
}
.ip-beans {
font-size: 30rpx;
text {
color: #f1c40f;
}
}
.text {
margin-top: 4rpx;
font-size: 24rpx;
color: #bdbdbd;
}
}
.give-away-btn {
width: 176rpx;
height: 60rpx;
background: #f75348;
border-radius: 30rpx;
color: #ffffff;
padding: 0 !important;
margin: 0 !important;
font-size: 28rpx;
line-height: 60rpx;
}
}
}
}
.mark {
position: fixed;
height: 100vh;
background: rgba(0, 0, 0, 0.1);
left: 0%;
right: 0%;
top: 0;
z-index: 100;
}
style>