效果预览

主要需求
- 下拉面板吸附至相对某个自定义元素的位置(例如相对输入框+输入框高度的位置)。
- 下拉面板不受容器的
overflow影响(下拉面板不能被overflow:hidden裁剪或导致容器出现滚动条)
Teleport 相关知识
<Teleport>是一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。
Vue文档中的说明
实现细节
使下拉面板不受容器overflow影响
使用<Teleport to="body"></Teleport> 包裹下拉面板的template部分。下拉面板的dom直接挂载到body下,脱离了当前文档流,自然不受父级overflow属性的影响。
是下拉面板吸附至输入框的底部
为输入框绑定模板引用:
<a-input ref="Input" />
script setup中获取模板引用:
const Input = ref();
# 或 两种写法等同
const Input = useTemplateRef("Input");
实时获取输入框位置:
import { useElementBounding } from "@vueuse/core"; # 建议安装使用vueuse
const { top, left, height } = useElementBounding(Input);
const popupStyle = computed(() => ({
position: "absolute",
top: top.value + height.value + "px",
left: left.value + "px",
zIndex: 9999,
}));
top、left、 height都是响应式引用,会随着Input元素位置变化而变化(这里暂不讨论实现方式,是浏览器原生API功能)。在计算属性中构建下拉面板的CSS属性,绑定到下拉面板元素上即可。
<div class="client-selecter" :style="{ ...otherStyle, ...popupStyle }" ...
# 多个css属性对象,建议将popupStyle放在最后,重复的属性后面的属性会覆盖前面的

