当前位置:   article > 正文

vue3 根据点击位置,实现一个用户头像弹框定位_前端vue怎么根据图片的点位定位元素的位置

前端vue怎么根据图片的点位定位元素的位置

vue3 根据点击位置,实现一个用户头像弹框定位

需求背景

最近在做直播后台,涉及到对用户的一些操作,比如关注/取关/禁言/踢出直播间。多个地方都要用,需要封装一个弹框组件

效果图

Jan-25-2024 18-12-39.gif

实现过程分析

  1. 根据点击元素,获取元素的位置
  2. 动态设置元素top,left位置

top 和 left 如何获取

根据 点击事件event参数,来获取位置,根据需要来实际计算位置

  • 元素距离左边的距离 + 元素本身的宽度

获取元素top/left,其实直接用getBoundingClientRect 里的bottom / right 即可

image.png

代码实现

export const getCurrentDialogXY = (event: Event) => {
  const target = event.target as HTMLElement
  const { bottom, right } = target.getBoundingClientRect()
  return { bottom, right }
}
  • 1
  • 2
  • 3
  • 4
  • 5

调用


```js
const avatarHandler = (event: Event) => {
  const { right, bottom } = getCurrentDialogXY(event)
  currentX.value = right
  currentY.value = bottom
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

传入子组件,在子组件内接收到left/top 重新定位即可

    <user-info-dialog
        :left="currentX"
        :top="currentY"
    />
  • 1
  • 2
  • 3
  • 4
<div ref="userInfoRef" class="dialog-wrap" :style="{ top: top + 'px', left: left + 'px' }"></div>
  • 1

细节处理

  1. 通过设置,你会发现弹框始终定位在元素右下角,可以根据自身需求,设置元素位置

image.png

image.png

通过监听弹框的ref(弹框有显示隐藏逻辑,所以监听弹框的ref即可,然后动态设置位置),

watchEffect(() => {
  const userInfoRefValue = userInfoRef.value
  if (userInfoRefValue) {
    const offsetHeight = userInfoRefValue.offsetHeight // 获取弹框的高度
    const offsetWidth = userInfoRefValue.offsetWidth // 获取元素的宽度

    // 不管弹框显示是左侧还是右侧,根据需求 都需要 减去 弹框的高度 - 用户头像高度的一半 进行定位
      propTop.value = props.top - offsetHeight - userAvatarWidth.value / 2
      
    // 如果是弹框显示在左侧,需要减去弹框的宽度 - 头像的宽度
    if (props.roleEnumType === 1) {
      propLeft.value = props.left - offsetWidth - userAvatarWidth.value
    }
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  1. 弹框打开之后,要点击所有位置,都可以关闭
  • 那我们就需要实现一个朦层(透明色),点击朦层,触发关闭即可

image.png

你会发现,其实我们的整个元素,是直接在根节点上,根常规里的,每个弹框,必须要绑定在循环里,才能做一一对应的关系,怎么不太一样呢?
这里是用到的

vue3中的Teleport:将其插槽内容渲染到 DOM 中的另一个位置
这对于我们层级比较多,做全局定位,脱离当前元素,非常好用!!!

image.png
当我们触发关闭事件,抛出去让父组件处理即可

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/49276
推荐阅读
相关标签
  

闽ICP备14008679号