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 中的另一个位置 这对于我们层级比较多,做全局定位,脱离当前元素,非常好用!!!

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

相关推荐
帅帅哥的兜兜1 小时前
next.js实现项目搭建
前端·react.js·next.js
筱歌儿1 小时前
css 左右布局
前端·css
GISer_Jing2 小时前
编译原理AST&以Babel为例进行解读、Webpack中自定义loader与plugin
前端·webpack·node.js
GISer_Jing2 小时前
Webpack中Compiler详解以及自定义loader和plugin详解
前端·webpack·node.js
浩~~2 小时前
CSS常用选择器
前端·css
于慨2 小时前
uniapp+vite+cli模板引入tailwindcss
前端·uni-app
yunvwugua__2 小时前
Python训练营打卡 Day26
前端·javascript·python
满怀10152 小时前
【Django全栈开发实战】从零构建企业级Web应用
前端·python·django·orm·web开发·前后端分离
Darling02zjh3 小时前
GUI图形化演示
前端
Channing Lewis3 小时前
如何判断一个网站后端是用什么语言写的
前端·数据库·python