业务逻辑:获取后端数据,渲染后右击某一项数据,在该项右上角展示弹出框,弹出框内有一个按钮,可以点击“重点关注”,点击“重点关注”后,传递频道id调用后端关注接口
思路1:使用element-plus的弹出框组件Popover
可以使用弹出框组件Popover ,但是弹出框的逻辑不能太复杂,如果需要弹出框有一个按钮,并且点击按钮弹出框取消这个逻辑不好处理,因为需要为每个弹出框设置Visible控制,一旦点击Visible=true
,所有弹出框都显示出来了,只能为每个弹出框设置不同的Visible属性控制,这样就增加了开发难度,并且代码不好维护。
用组件不适合处理复杂逻辑,只用弹出框纯展示时,才适合用组件,如果弹出框需要调用接口则不适合
思路2:自定义弹窗组件
-
获取右键点击事件
e.pageX
——相对整个页面的坐标e.layerX
——相对当前选择元素坐标系的border左上角开始的坐标e.offsetX
——相对当前选择元素坐标系的border左上角开始的坐标e.clientX
——相对可视区域的坐标e.x
——相对可视区域的坐标我们需要用
e.layerX
const isPop = ref(false) const mouse = reactive({ left: 0, top: 0 }) const channelId = ref(0) const pop = (e, id) => { // 1.1 获取x、y坐标轴---e.layerX相对当前选择元素坐标系的border左上角开始的坐标 mouse.left = e.layerX mouse.top = e.layerY // 1.2 显示弹出框 isPop.value = true // 1.3 获取id channelId.value = id // 1.3 添加鼠标松开事件 document.addEventListener("mouseup", eventHandle); console.log(e); }
此处需要监听
mouseup
,因为当鼠标右击时,也需要对事件进行监听。 -
监听事件函数
const eventHandle = () => { isPop.value = false; }
-
销毁鼠标松开事件
这里需要对事件销毁,否则事件积累多了会导致性能变差
onUnmounted(() => { document.removeEventListener("mouseup", eventHandle) })
-
弹出框点击事件
const channelHandle = () => { // 2.4.1 根据id发起网络请求 ..... console.log(channelId.value); }
-
在
template
使用<div v-if="isPop" class="pop-channel" :style="{ 'left': mouse.left + 'px', 'top': mouse.top + 'px' }"> <div @mouseup="channelHandle">点击</div> </div>
这里为什么要用
mouseup
?,因为mouseup
、click
,触发事件是有执行顺序的,若在同一个元素上按下并松开鼠标左键,会依次触发mousedown
、mouseup
、click
,前一个事件执行完毕才会执行下一个事件;如果此处用
click
,监听事件又使用的是mouseup
,会导致此处的click
事件不被执行。需要改为mouseup
事件