组件引入:
<Pop ref=“pop” @handle=“openVideo” @closePop=“closePop” />
marker.on(‘click’,async (e: any) => {
pop.value.show(e.pixel)
const list = await getFunc(item)
item.list = list
pop.value.setData(item)
})
组件内容:
<template>
<div v-if="showMenu" class="popup-menu" :style="{top: clientY, left: clientX, width: clientW}" v-loading="loading">
<div v-if="!loading">
<el-icon class="icon-close" @click="close"><Close /></el-icon>
<div class="title"></div>
<div class="box">
</div>
</div>
</div>
</template>
<script setup lang='ts'>
import { onMounted, ref } from 'vue';
import { Close } from '@element-plus/icons-vue'
const emit = defineEmits<{
(e: 'handle'): void,
(e: 'closePop'): void,
}>()
// 初始值配置
const showMenu = ref(false)
const clientY = ref('')
const clientX = ref('')
const clientW = ref('0px')
const loading = ref(false)
const close = () => {
clientW.value = '0px'
showMenu.value = false
emit('closePop')
}
const show = (event: any) => {
setPopPosition(event, 320, 400)
showMenu.value = true
loading.value = true
setTimeout(() => {
clientW.value = '512px'
}, 0)
}
const setData = (data: any) => {
valueData.value = data
setTimeout(() => { loading.value = false }, 100)
}
const setPopPosition = (event: any, xWidth: number, yHeight: number) => {
let x: any = Number(event.x) + xWidth; //鼠标点击的x坐标
let y: any = Number(event.y) - yHeight; //鼠标点击的y坐标
clientX.value = (parseFloat(x) - 10) + "px";
clientY.value = (parseFloat(y) + 10) + "px";
let windowWidth: any = document.documentElement.clientWidth; // 实时屏幕宽度
let windowHeight: any = document.documentElement.clientHeight; // 实时屏幕高度
let menuWidth = 512;//菜单宽度,这个与.popup-menu样式对应的宽度一致
let menuHeight = windowHeight * 0.63; //菜单高度,根据菜单项自动计算的高度
if (parseFloat(x) + menuWidth > windowWidth) {
clientX.value = parseFloat(x) - menuWidth - 200 + "px";
}
if (parseFloat(y) + menuHeight > windowHeight) {
clientY.value = (parseFloat(windowHeight) -menuHeight - 50) + "px";
}
if (parseFloat(y) - 100 < 0) {
clientY.value = 100 + "px";
}
}
// 当视频窗口占用到弹窗位置时,移动以及恢复窗口
const removeXY = () => {
beforeX.value = clientX.value
let windowWidth: any = document.documentElement.clientWidth; // 实时屏幕宽度
// 计算视频窗口占用的宽高
const x = (windowWidth * 0.25) + 217 + 24
if (Number(clientX.value.replace('px', '')) < x) {
clientX.value = x + 70 + 'px'
}
}
const restoreXY = () => {
if (clientX.value !== beforeX.value) clientX.value = beforeX.value
}
defineExpose({
show,
setData,
removeXY,
restoreXY
})
onMounted(()=>{})
</script>
<style scoped lang='less'>
.popup-menu {
position: fixed;
background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.8) 100%);
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.08);
border-radius: 8px;
padding: 24px 0px 24px 24px;
transition: all 0.2s;
height: 63vh;
z-index: 1002;
.icon-close {
position: absolute;
top: 28px;
right: 30px;
font-size: 16px;
cursor: pointer;
}
.title {
font-size: 20px;
height: 28px;
line-height: 28px;
font-weight: 500;
color: @back-color;
}
.box {
height: calc(63vh - 52px);
overflow-y: auto;
padding-right: 24px;
}
</style>