You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
xuan-pay-cweb/components/next-bubble-menu/next-bubble-menu.vue

298 lines
7.3 KiB

<template>
<view class="next-bubble-menu"
>
<view @click.stop="showContainer">
<slot></slot>
</view>
<view class="mask" v-show="show && showUi" @click.stop="show=false"></view>
<view class="container" v-show="show && showUi">
<view class="block" :style="{left: `calc(50% - ${(width*0.5).toFixed(0)}rpx)`}">
<view class="arrow"
:style="{
left:0,
top: showTop && (arrowTop+12)+'rpx'
}" @click.stop>
</view>
<view class="list-container"
:style="'height:'+(dHeight?dHeight+'rpx':'auto')+';max-height:'+dMaxHeight+'rpx;border-radius:'+radius+'rpx;width:'+width+'rpx;left:'+ relativeAllow +'rpx;'">
<view :class="'list-item '+(index==dataList.length-1?'':'bt')" v-for="(item,index) in dataList" :key="index" @click.stop="clickItem(item)">
<image class="list-item-image" :src="item.iconSrc" v-if="item.iconSrc" />
<text class="list-item-text">{{item.text}}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
let closeOtherHooks = new Set()
const closeOtherPopUp = (closePopUp) => {
closeOtherHooks.forEach(hook => {
if (closePopUp !== hook) { //closePopUp当前页面关闭方法,hook所有页面的关闭方法
hook()
}
})
}
export default {
props: {
bingEleId: {
type: String,
default: ''
},
//气泡框数据源
dataList: {
type: Array,
default: () => {
return []
}
},
hasBar: {
type: Boolean,
default: true
},
radius: {
type: Number,
default: 8
},
dWidth: {
type: Number,
default: 0
},
dHeight: {
type: Number,
default: 0
},
dMaxHeight: {
type: Number,
default: 400
},
relativeAllow: {
type: Number,
default: -30
}
},
data() {
return {
show: false,
width: 0,
height: 0,
left: 0,
top: 0,
bottom: 0,
rectTop: 0,
screenWidth: 0,
showTop: false,
arrowTop: 0,
showUi: false
}
},
mounted() {
const closePopUp = () => {
this.show = false;
}
closeOtherHooks.add(closePopUp) //closeOtherHooks每个页面的关闭方法都加上
this.closePopUp = closePopUp
this.$nextTick(() => {
if (!this.bingEleId) return
// #ifdef APP-PLUS
uni.createSelectorQuery().in(this).select('.next-bubble-menu').boundingClientRect(res => {
let difference = res.left
uni.createSelectorQuery().select('#' + this.bingEleId).boundingClientRect(rect => {
const systemInfo = uni.getSystemInfoSync()
const windowHeight = systemInfo.windowHeight
this.screenWidth = systemInfo.screenWidth
if (!this.dWidth) {
this.width = this.px2rpx(rect.width, this.screenWidth)
} else {
let screenW = this.px2rpx(this.screenWidth, this.screenWidth)
this.width = this.dWidth > screenW ? screenW : this.dWidth
}
this.height = rect.height
this.rectTop = rect.top
this.bottom = windowHeight - rect.bottom
}).exec()
}).exec()
// #endif
// #ifndef APP-PLUS
uni.createSelectorQuery().in(this).select('.next-bubble-menu').boundingClientRect(res => {
let difference = res.left
uni.createSelectorQuery().select('#' + this.bingEleId).boundingClientRect(rect => {
const systemInfo = uni.getSystemInfoSync()
const windowHeight = systemInfo.windowHeight
this.screenWidth = systemInfo.screenWidth
if (!this.dWidth) {
this.width = this.px2rpx(rect.width, this.screenWidth)
} else {
let screenW = this.px2rpx(this.screenWidth, this.screenWidth)
this.width = this.dWidth > screenW ? screenW : this.dWidth
}
this.height = rect.height
this.rectTop = rect.top
this.bottom = windowHeight - rect.bottom
}).exec()
}).exec()
// #endif
})
},
methods: {
showContainer() {
if (!this.bingEleId) return
else this.show = !this.show
if (this.show) {
closeOtherPopUp(this.closePopUp) //关掉其他的
this.$nextTick(res => {
// #ifdef APP-PLUS
let view = uni.createSelectorQuery().in(this).select(".list-container")
view.boundingClientRect(res => {
let arrHeight = res.height
let height = this.bottom - arrHeight - 15
if (height < 0) {
this.showTop = true
this.top = this.px2rpx((this.rectTop - arrHeight - 10), this
.screenWidth)
this.arrowTop = this.px2rpx(arrHeight - 5, this.screenWidth)
} else {
this.showTop = false
this.top = this.px2rpx(this.rectTop + this.height + 10, this
.screenWidth)
}
this.$nextTick(() => {
this.showUi = true
})
}).exec()
// #endif
// #ifndef APP-PLUS
uni.createSelectorQuery().in(this).select('.list-container').boundingClientRect(res => {
const left = res.left
let arrHeight = res.height
let height = this.bottom - arrHeight - 15
if (height < 0) {
this.showTop = true
if (this.hasBar) {
// #ifdef H5
this.top = this.px2rpx((this.rectTop - arrHeight + 35), this
.screenWidth)
// #endif
// #ifndef H5
this.top = this.px2rpx((this.rectTop - arrHeight - 10), this
.screenWidth)
// #endif
} else {
this.top = this.px2rpx((this.rectTop - arrHeight - 10), this
.screenWidth)
}
this.arrowTop = this.px2rpx(arrHeight - 5, this.screenWidth)
} else {
this.showTop = false
if (this.hasBar) {
// #ifdef H5
this.top = this.px2rpx(this.rectTop + this.height + 54, this
.screenWidth)
// #endif
// #ifndef H5
this.top = this.px2rpx(this.rectTop + this.height + 10, this
.screenWidth)
// #endif
} else {
this.top = this.px2rpx(this.rectTop + this.height + 10, this
.screenWidth)
}
}
this.$nextTick(() => {
this.showUi = true
})
}).exec()
// #endif
})
}
},
px2rpx(px, screenWidth) {
return px / (screenWidth / 750)
},
//点击选项
clickItem(item) {
this.show = false
this.$emit('change', item)
}
}
}
</script>
<style lang="scss" scoped>
$bgColor:#3da7e7;
$ftColor:#ffffff;
.mask{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999999 !important;
// background:rgba(0, 0, 0, 0.5);
}
.next-bubble-menu {
position: relative;
border: solid transparent 1px;
}
.block {
/* position: fixed; */
position: absolute;
z-index: 99999999 !important;
}
.container{
position: relative;
}
.list-container {
box-sizing: border-box;
overflow: auto;
// padding: 16rpx 20rpx;
background-color: $bgColor;
box-shadow: 2rpx 4rpx 10rpx rgba(0,0,0,.1);
}
.arrow {
width: 0;
height: 0;
margin: -10rpx auto 0;
border-top: 10rpx solid transparent;
border-bottom: 10rpx solid $bgColor;
border-right: 10rpx solid transparent;
border-left: 10rpx solid transparent;
}
.list-item {
line-height: 80rpx;
text-align: center;
color: $ftColor;
&:active{
background-color:$ftColor;
color: $bgColor;
}
}
.bt{
border-bottom: 1px solid $ftColor;
}
.list-item .list-item-image {
display: inline-block;
vertical-align: middle;
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.list-item .list-item-text {
vertical-align: middle;
}
</style>