这两天接到个新需求,要求当用户点击一个元素时,让popover弹窗的位置跟随鼠标点击的位置进行显示。这需求乍一听好像很简单,但是细品,嗯··· ···吐槽归吐槽,事情总是要完成的。打开element plus官网我们发现,一般的popver用法就是让这个组件绑定一个button按钮,然后点击,悬浮或者别的方式让其展示。现在我们是绑定一个大的元素(比如一个div..)要求在div内点击任何一处,弹出框就展示在该处。
在官网中我们可以看到这么个属性“virtual-ref”,我们通过这个属性来给popver绑定一个元素(假设为<span><span>),我们通过更改绑定的元素(<span><span>)的位置,从而开控制popver的显示位置。
此时我们不难想到,要求实现鼠标跟随,就得获取鼠标点击的位置,当获取到鼠标点击的位置的时候,我们把(<span><span>)的style属性的位置进行绑定,即可实现位置的跟随,我们可以这样写,如下所示:
<template>
<div class="homebox">
<div style="
width: 25vw;
height: 45vh;
background-color: aquamarine;
cursor: pointer;
margin: 10% 0 0 20%;
display: grid;
place-items: center;
" @click="handleClick">
元素框
<!-- 触发元素,它是一个不可见的元素,用于触发 popover -->
<span ref="trigger" style="position: absolute; top: 0; left: 0; width: 0; height: 0"></span>
<el-popover ref="popover" :virtual-ref="trigger" placement="right" :width="200"
v-model:visible="visible">
<!-- 一个关闭的x,可自行换成图标 -->
<div style="position: absolute; top: -3px; right: 3px; cursor: pointer" @click="visible = false">
x
</div>
<div>···内容···</div>
</el-popover>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const visible = ref(false);
const trigger = ref(null);
const popover = ref(null);
const handleClick = (event) => {
// 设置触发元素的位置为鼠标点击的位置,条件判断:当在元素框内点击,并且弹出框状态为关闭时,再展示
if (trigger.value && !visible.value) {
trigger.value.style.top = `${event.clientY}px`;
trigger.value.style.left = `${event.clientX}px`;
visible.value = true;
}
};
</script>
效果如下图:
我们点击元素框,popver出现,当我们点击右上角“”x“”时关闭,再次点击元素内别的地方,popver再次出现在点击的位置,至此,该功能改造完成!
补充一点:popver触发方式可以更改,不仅限于点击,具体的还行自行查看官网哈!element plus中Popover 气泡卡片文档说明