初始化万家商超用户端仓库
This commit is contained in:
410
components/benben-position-popup/benben-position-popup.vue
Normal file
410
components/benben-position-popup/benben-position-popup.vue
Normal file
@ -0,0 +1,410 @@
|
||||
<template>
|
||||
<view class="p_wrapper" style="z-index: 19999" v-if="isShow">
|
||||
<view
|
||||
ref="mask"
|
||||
catchtouchmove="true"
|
||||
bubble="true"
|
||||
class="mask"
|
||||
style="z-index: 20000"
|
||||
:style="maskStyle"
|
||||
@touchmove.stop.prevent="moveHandle"
|
||||
@click="close()"
|
||||
:class="[notNvueAni ? 'not_animation_show_mask' : 'not_animation_hide_mask']"
|
||||
></view>
|
||||
<view
|
||||
ref="popup"
|
||||
id="popup"
|
||||
class="content"
|
||||
:class="{
|
||||
not_def_show: type == 'zoom',
|
||||
not_def_show_f: type != 'zoom',
|
||||
not_nvue_animation_show: notNvueAni && type == 'zoom',
|
||||
not_nvue_animation_hide: !notNvueAni && type == 'zoom',
|
||||
not_nvue_animation_show_f: notNvueAni && type != 'zoom',
|
||||
not_nvue_animation_hide_f: !notNvueAni && type != 'zoom',
|
||||
}"
|
||||
style="z-index: 20001"
|
||||
:style="contentStyle"
|
||||
>
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
const animation = weex.requireModule('animation')
|
||||
// #endif
|
||||
export default {
|
||||
name: 'benben-position-popup',
|
||||
props: {
|
||||
// 是否显示蒙层
|
||||
maskHide: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 弹窗模式 有 zoom fade
|
||||
type: {
|
||||
type: String,
|
||||
default: 'zoom',
|
||||
},
|
||||
// 内容区 宽度 单位rpx
|
||||
width: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 内容区 高度 单位 rpx
|
||||
height: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 弹窗定位 顶部距离 可ref 调用时传入 ref没有传入这个就是默认定位 单位px
|
||||
top: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 弹窗定位 左侧距离 可ref 调用时传入 ref没有传入这个就是默认定位 单位px
|
||||
left: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 是否有 原生状态栏
|
||||
hasNav: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 自定义弹出方向
|
||||
popupOrigin: {
|
||||
type: String,
|
||||
default: 'left top',
|
||||
},
|
||||
// 是否 开启自适应
|
||||
adaption: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
origin: 'left top', // 动画的定位点
|
||||
x: 0, // 弹窗弹出位置 定位点
|
||||
y: 0, // 弹窗弹出位置 定位点
|
||||
maxX: 0, // 最大 x 值 用于判断弹窗定位点
|
||||
maxY: 0, // 最大 y 值 用于判断弹窗定位点
|
||||
winH: 0, // 屏幕 总高度
|
||||
winW: 0, // 屏幕 总宽度
|
||||
windowTop: 0, // h5 下的顶部距离
|
||||
notNvueAni: false, // 控制非nvue动画
|
||||
hideTarget: 'scale(0,0)', // 隐藏目标
|
||||
isShow: false, // 是否显示
|
||||
statusBarHeight: 0, // 手机状态栏高度
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 一些状态下 阻止 遮罩下滚动
|
||||
moveHandle() {
|
||||
return
|
||||
},
|
||||
// 打开弹窗
|
||||
async open(e, isMe) {
|
||||
console.log('benben-position-popup', e.changedTouches)
|
||||
this.comMax()
|
||||
let x, y
|
||||
if (isMe && e) {
|
||||
// 自己传入 x y 定位
|
||||
x = e.x
|
||||
y = e.y
|
||||
} else if (e) {
|
||||
// 自动传入长按事件 对象
|
||||
// app nvue 的情况 拿取 长按位置
|
||||
// #ifdef APP-NVUE
|
||||
if (Array.isArray(e.changedTouches) && e.changedTouches.length > 0) {
|
||||
// nvue 安卓下 获取pageX pageY 会有问题 所以 统一使用 screenX screenY
|
||||
x = e.changedTouches[0].screenX
|
||||
y = e.changedTouches[0].screenY - this.statusBarHeight - (this.hasNav ? 40 : 0)
|
||||
} else {
|
||||
const { position } = e
|
||||
x = position.x
|
||||
y = position.y
|
||||
}
|
||||
// #endif
|
||||
// app 非nvue 的情况 拿取 长按位置
|
||||
// #ifdef APP-VUE
|
||||
if (Array.isArray(e.changedTouches) && e.changedTouches.length > 0) {
|
||||
x = e.changedTouches[0].clientX
|
||||
y = e.changedTouches[0].clientY
|
||||
console.log('x', x)
|
||||
console.log('y', y)
|
||||
} else {
|
||||
const { position } = e
|
||||
x = position.x
|
||||
y = position.y
|
||||
}
|
||||
// #endif
|
||||
// 小程序的 情况 拿取 长按位置
|
||||
// #ifdef MP
|
||||
|
||||
x = e.touches[0].clientX
|
||||
y = e.touches[0].clientY
|
||||
// #endif
|
||||
// h5的 情况 拿取 长按位置
|
||||
// #ifdef H5
|
||||
if (Array.isArray(e.changedTouches) && e.changedTouches.length > 0) {
|
||||
x = e.changedTouches[0].clientX
|
||||
y = e.changedTouches[0].clientY + this.windowTop
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
// 固定定位 props 传入
|
||||
if (!e) {
|
||||
x = this.left
|
||||
y = this.top
|
||||
}
|
||||
|
||||
const originArr = this.popupOrigin.split(' ')
|
||||
let originX = originArr[0]
|
||||
let originY = originArr[1]
|
||||
if (this.adaption) {
|
||||
if (x > this.maxX && y > this.maxY) {
|
||||
// this.origin = 'right bottom';
|
||||
originX = 'right'
|
||||
originY = 'bottom'
|
||||
} else if (x < uni.upx2px(this.width) && y < uni.upx2px(this.height)) {
|
||||
originX = 'left'
|
||||
originY = 'top'
|
||||
} else if (x > this.maxX) {
|
||||
originX = 'right'
|
||||
} else if (y > this.maxY) {
|
||||
originY = 'bottom'
|
||||
} else if (x < uni.upx2px(this.width)) {
|
||||
originX = 'left'
|
||||
} else if (y < uni.upx2px(this.height)) {
|
||||
originY = 'top'
|
||||
}
|
||||
this.origin = originX + ' ' + originY
|
||||
}
|
||||
// 检测到 极限位置 开边弹出方向
|
||||
if (this.adaption) {
|
||||
if (originY === 'top') {
|
||||
this.y = y
|
||||
} else {
|
||||
this.y = y - uni.upx2px(this.height) > 0 ? y - uni.upx2px(this.height) : 0
|
||||
}
|
||||
if (originX === 'left') {
|
||||
this.x = x
|
||||
} else {
|
||||
this.x = x - uni.upx2px(this.width) > 0 ? x - uni.upx2px(this.width) : 0
|
||||
}
|
||||
} else {
|
||||
this.x = x
|
||||
this.y = y
|
||||
}
|
||||
this.isShow = true
|
||||
// #ifndef APP-NVUE
|
||||
setTimeout(() => {
|
||||
this.notNvueAni = true
|
||||
}, 10)
|
||||
// #endif
|
||||
this.hideTarget = 'scale(0,0)'
|
||||
setTimeout(() => {
|
||||
this.animationShow()
|
||||
}, 30)
|
||||
},
|
||||
close() {
|
||||
// #ifdef APP-NVUE
|
||||
this.animationHide()
|
||||
// #endif
|
||||
// #ifndef APP-NVUE
|
||||
this.notNvueAni = false
|
||||
setTimeout(() => {
|
||||
this.isShow = false
|
||||
}, 300)
|
||||
// #endif
|
||||
},
|
||||
// 检测极限位置
|
||||
comMax() {
|
||||
let sizeArr = [this.width, this.height]
|
||||
let width = uni.upx2px(Number(sizeArr[0]))
|
||||
let height = uni.upx2px(Number(sizeArr[1]))
|
||||
this.maxX = this.winW - width
|
||||
this.maxY = this.winH - height
|
||||
},
|
||||
// nvue 打开 动画
|
||||
animationShow() {
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
let tranget = ''
|
||||
if (this.type === 'zoom') {
|
||||
tranget = 'scale(1,1)'
|
||||
}
|
||||
animation.transition(this.$refs.popup, {
|
||||
styles: {
|
||||
transformOrigin: this.origin,
|
||||
transform: tranget,
|
||||
opacity: 1,
|
||||
},
|
||||
duration: 200, //ms
|
||||
timingFunction: 'ease',
|
||||
})
|
||||
|
||||
if (this.$refs.mask) {
|
||||
animation.transition(this.$refs.mask, {
|
||||
styles: {
|
||||
opacity: 1,
|
||||
},
|
||||
duration: 200, //ms
|
||||
timingFunction: 'ease',
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
// nvue 关闭 动画
|
||||
animationHide() {
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
this.$nextTick(() => {
|
||||
animation.transition(
|
||||
this.$refs.popup,
|
||||
{
|
||||
styles: {
|
||||
transform: this.type === 'zoom' ? this.hideTarget : '',
|
||||
transformOrigin: this.origin,
|
||||
opacity: 0,
|
||||
},
|
||||
duration: 200, //ms
|
||||
timingFunction: 'ease',
|
||||
},
|
||||
() => {
|
||||
this.isShow = false
|
||||
}
|
||||
)
|
||||
|
||||
if (this.$refs.mask) {
|
||||
animation.transition(this.$refs.mask, {
|
||||
styles: {
|
||||
opacity: 0,
|
||||
},
|
||||
duration: 200, //ms
|
||||
timingFunction: 'ease',
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
// 获取系统 信息
|
||||
getSystemSize() {
|
||||
this.$nextTick(() => {
|
||||
const winSize = uni.getSystemInfoSync()
|
||||
const { windowHeight, windowWidth, statusBarHeight } = winSize
|
||||
this.statusBarHeight = statusBarHeight
|
||||
this.winH = windowHeight
|
||||
this.winW = windowWidth
|
||||
// #ifdef H5
|
||||
const { windowTop } = winSize
|
||||
this.windowTop = windowTop
|
||||
// #endif
|
||||
})
|
||||
},
|
||||
},
|
||||
// 组件初始化
|
||||
created() {
|
||||
this.getSystemSize()
|
||||
},
|
||||
computed: {
|
||||
// 蒙层样式
|
||||
maskStyle() {
|
||||
return this.maskHide ? 'background-color: rgba(0, 0, 0, .4);' : ''
|
||||
},
|
||||
// 主弹窗样式
|
||||
contentStyle() {
|
||||
let width, height, x, y
|
||||
switch (this.type) {
|
||||
case 'zoom': // 当default时 样式
|
||||
width = this.width
|
||||
height = this.height
|
||||
x = this.x
|
||||
y = this.y
|
||||
let origin = this.origin
|
||||
return `left: ${x}px; top: ${y}px; width: ${width}rpx; height: ${height}rpx; transform-origin: ${origin};`
|
||||
default:
|
||||
width = this.width
|
||||
height = this.height
|
||||
x = this.x
|
||||
y = this.y
|
||||
return `left: ${x}px; top: ${y}px; width: ${width}rpx; height: ${height}rpx;`
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.p_wrapper {
|
||||
/* position: fixed; */
|
||||
position: fixed;
|
||||
/* #ifndef APP-NVUE */
|
||||
z-index: 10000;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.mask {
|
||||
/* #ifndef APP-NVUE */
|
||||
z-index: 10000;
|
||||
/* #endif */
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
/* #ifndef APP-NVUE */
|
||||
z-index: 10001;
|
||||
/* #endif */
|
||||
position: fixed;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.not_def_show {
|
||||
transform: scale(0, 0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.not_def_show_f {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.not_animation_show_mask {
|
||||
transition: opacity 200;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.not_animation_hide_mask {
|
||||
transition: opacity 200;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
.not_nvue_animation_show {
|
||||
transition: all 200ms;
|
||||
transform: scale(1, 1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.not_nvue_animation_hide {
|
||||
transition: all 200ms;
|
||||
transform: scale(0, 0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.not_nvue_animation_show_f {
|
||||
transition: all 400ms;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.not_nvue_animation_hide_f {
|
||||
transition: all 400ms;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
</style>
|
||||
Reference in New Issue
Block a user