弹出框-两种实现方案

80 阅读2分钟

业务逻辑:获取后端数据,渲染后右击某一项数据,在该项右上角展示弹出框,弹出框内有一个按钮,可以点击“重点关注”,点击“重点关注”后,传递频道id调用后端关注接口

思路1:使用element-plus的弹出框组件Popover

可以使用弹出框组件Popover ,但是弹出框的逻辑不能太复杂,如果需要弹出框有一个按钮,并且点击按钮弹出框取消这个逻辑不好处理,因为需要为每个弹出框设置Visible控制,一旦点击Visible=true,所有弹出框都显示出来了,只能为每个弹出框设置不同的Visible属性控制,这样就增加了开发难度,并且代码不好维护。

用组件不适合处理复杂逻辑,只用弹出框纯展示时,才适合用组件,如果弹出框需要调用接口则不适合

思路2:自定义弹窗组件

  1. 获取右键点击事件

    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,因为当鼠标右击时,也需要对事件进行监听。

  2. 监听事件函数

    const eventHandle = () => {
      isPop.value = false;
    }
    
  3. 销毁鼠标松开事件

    这里需要对事件销毁,否则事件积累多了会导致性能变差

    onUnmounted(() => {
      document.removeEventListener("mouseup", eventHandle)
    })
    
  4. 弹出框点击事件

    const channelHandle = () => {
      // 2.4.1 根据id发起网络请求
      .....
      console.log(channelId.value);
    }
    
  5. template使用

        <div v-if="isPop" class="pop-channel" :style="{ 'left': mouse.left + 'px', 'top': mouse.top + 'px' }">
          <div @mouseup="channelHandle">点击</div>
        </div>
    

    这里为什么要用mouseup?,因为mouseupclick,触发事件是有执行顺序的,若在同一个元素上按下并松开鼠标左键,会依次触发mousedownmouseupclick,前一个事件执行完毕才会执行下一个事件;

    如果此处用click,监听事件又使用的是mouseup,会导致此处的click事件不被执行。需要改为mouseup事件