分享Vue3中使用Floating UI的小例子

Floating UI是什么?

Floating UI( floating-ui.com )是Popper.js的升级版,把官网的介绍翻译过来就是:

一个 JavaScript 库,用于定位浮动元素并为其创建交互。 "Smart Anchor Positioning"(智能锚定定位)是该库提供的一个功能,它可以将浮动元素相对于另一个元素进行定位,并确保它保持在可视区域内,避免与其他元素发生碰撞。这使得你可以优化地定位工具提示(tooltips)、弹出框(popovers)或下拉菜单(dropdowns)等浮动元素。
简而言之,该库可以帮助你轻松地将浮动元素放置在其他元素旁边,并自动调整其位置,以避免与其他元素重叠或超出可视区域。这提供了更好的用户体验,并确保了浮动元素的可见性和可用性。

安装模块

npm install @floating-ui/vue

Vue3代码

html 复制代码
<template>
  <div
    style="
      display: flex;
      justify-content: center;
      align-items: center;
      margin: auto;
      height: 100%;
    "
  >
    <div style="height: 100%; width: 100%; text-align: center">
      <div style="height: 1000px"></div>
      <span ref="reference">
        <el-button @click="isShow = !isShow">trigger</el-button>
      </span>
      <div
        v-if="isShow"
        ref="floating"
        :style="{ left: floatingStyles.left, top: floatingStyles.top }"
        style="background: pink; width: 50px; height: 150px; position: absolute"
      >
        Floating
      </div>
      <div style="height: 1000px"></div>
    </div>
  </div>
</template>
js 复制代码
<script setup lang="ts">
import {
  arrow,
  useFloating,
  computePosition,
  shift,
  flip,
  offset,
} from "@floating-ui/vue";
import { watch } from "vue";
import { ref, onMounted, nextTick, watchEffect } from "vue";

let isShow = ref(false);
const reference = ref<HTMLElement | null>(null);
let floating = ref<HTMLElement | null>(null);

// 初始化,中间件middleware还可以设置箭头之类的,这里我没有配置
const { floatingStyles, middlewareData } = useFloating(reference, floating, {
  middleware: [],
});
console.log(
  "初始化",
  floatingStyles.value,
  floatingStyles.value.left,
  floatingStyles.value.top
);
const middleware = [shift(), flip(), offset(10)];

// 核心代码,调用FloatingUI的computePosition函数,自动调整floating元素的位置
const updatePosition = () => {
  computePosition(
    reference.value as HTMLElement,
    floating.value as HTMLElement,
    {
      middleware, // 按需引用的中间件
      placement: "bottom", // 指定初始化浮动位置
    }
  ).then(({ x, y }) => {
    // computePosition根据传入参数计算目标元素和浮动元素位置,
    // 异步返回浮动元素坐标后可手动设置浮层位置
    Object.assign(floating.value.style, {
      left: `${x}px`,
      top: `${y}px`,
    });
    console.log(
      "调整位置",
      floatingStyles.value,
      floatingStyles.value.left,
      floatingStyles.value.top
    );
  });
};

// 浮动元素显示时,启动resize和scroll的监听,否则清除监听
watch(
  () => isShow.value,
  () => {
    if (isShow.value) {
      nextTick(() => {
        updatePosition();
        // 这里注意应该还要做一下debounce的处理
        window.onresize = function () {
          updatePosition();
        };
        window.onscroll = function () {
          updatePosition();
        };
      });
    } else {
      window.onresize = null;
      window.onscroll = null;
    }
  }
);
</script>
scss 复制代码
<style lang="scss">
#app {
  height: 100%;
}
</style>

效果:

初始化状态,floating元素默认在按钮下方

滚动条往上,floating元素的下端即将滚动出视口时,floating元素自动调整到按钮上方

相关推荐
IT_陈寒3 小时前
SpringBoot这个自动配置坑我跳了三次
前端·人工智能·后端
kyriewen3 小时前
我用 AI 一周写完了整个项目,上线第一天就崩了——这是我踩过最贵的 5 个坑
前端·javascript·ai编程
牧艺4 小时前
从零到协同:构建类飞书在线文档系统的五个技术重难点
前端·人工智能
红尘散仙4 小时前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
袋鼠云数栈UED团队5 小时前
一套 Spec-First 的 AI 编程工作流
前端·人工智能
袋鼠云数栈前端5 小时前
一套 Spec-First 的 AI 编程工作流
前端·ai+
angerdream5 小时前
Android手把手编写儿童手机远程监控App之vue3 路由守卫
前端
不服老的小黑哥5 小时前
AI规范驱动编程-harness工程项目实战
前端
vivo互联网技术5 小时前
从 Web 到桌面:基于 Tauri 2.0 + Vue 3 打造 vivo 线下门店「大头贴」拍照体验系统
前端·rust
光影少年5 小时前
React 合成事件机制、和原生事件区别、事件冒泡阻止
前端·react.js·掘金·金石计划