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

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

需求背景

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

效果图

实现过程分析

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

top 和 left 如何获取

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

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

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

代码实现

js 复制代码
export const getCurrentDialogXY = (event: Event) => {
  const target = event.target as HTMLElement
  const { bottom, right } = target.getBoundingClientRect()
  return { bottom, right }
}

调用

scss 复制代码
```js
const avatarHandler = (event: Event) => {
  const { right, bottom } = getCurrentDialogXY(event)
  currentX.value = right
  currentY.value = bottom
}

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

js 复制代码
    <user-info-dialog
        :left="currentX"
        :top="currentY"
    />
js 复制代码
<div ref="userInfoRef" class="dialog-wrap" :style="{ top: top + 'px', left: left + 'px' }"></div>

细节处理

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

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

js 复制代码
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. 弹框打开之后,要点击所有位置,都可以关闭
  • 那我们就需要实现一个朦层(透明色),点击朦层,触发关闭即可

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

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

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

相关推荐
m0_7190841128 分钟前
React笔记张天禹
前端·笔记·react.js
Ziky学习记录42 分钟前
从零到实战:React Router 学习与总结
前端·学习·react.js
wuhen_n1 小时前
JavaScript链表与双向链表实现:理解数组与链表的差异
前端·javascript
wuhen_n1 小时前
JavaScript数据结构深度解析:栈、队列与树的实现与应用
前端·javascript
狗哥哥1 小时前
微前端路由设计方案 & 子应用管理保活
前端·架构
前端大卫2 小时前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘2 小时前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare2 小时前
浅浅看一下设计模式
前端
Lee川2 小时前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix3 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts