|
|
|
<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>
|