想要写一个Popover,计算元素位置使用的是floating-ui
,需要获取触发元素的Ref和Popover内容的Ref来进行定位。
触发元素和内容通过插槽传入,遇到的问题是如何获取插槽内元素的Ref
Popover 伪代码:
<template> <slot name="trigger" /> <teleport to="body"> <div v-if="show" class="absolute inset-0"> <slot /> </div> </teleport></template>
使用:
<Popover> <template #trigger> <button >test</button> </template> <div> Popover </div></Popover>
目前我能想到的办法就是在触发元素和内容外套一层div,然后用div的Ref
<script setup>const triggerRef = ref()const floatingRef = ref()</script><template> <div ref="triggerRef"> <slot name="trigger" /> </div> <teleport to="body"> <div ref="floatingRef" v-if="show" class="absolute inset-0"> <slot /> </div> </teleport></template>
但是这样就多了一层节点,在想能不能有更好的解决方案?
看了别的组件库,目前已经找到一种解决方案:
就是直接通过 useSlots()
获取插槽的 vNode,然后手动渲染,并绑定ref。
代码如下:
<script setup>import {ref, useSlots} from 'vue'const triggerRef = ref()const floatingRef = ref()const slots = useSlots()const triggerArr = slots?.trigger?.()// 获取vNode(真实场景,这一步需要校验插槽传过来的值。如果值是字符串或多个元素等情况,需要进一步处理)const TriggerVNode = triggerArr[0]</script><template> <TriggerVNode ref="triggerRef" /> <teleport to="body"> <div ref="floatingRef" v-if="show" class="absolute inset-0"> <slot /> </div> </teleport></template>
但是这样有个缺点,WebStorm 写插槽的时候不会有提示,甚至有警告
以上问题可以通过 Vue3.3 新增宏 defineSlots()
来解决,defineSlots()
用于定义插槽。
具体使用 查看Vue文档
在Vue中,你可以使用ref()
函数来获取插槽内元素的引用。ref()
函数返回一个响应式引用,可以用来访问DOM元素或组件实例。
在你的例子中,你可以在Popover组件的setup()
函数中创建一个ref
,并将其绑定到插槽元素上。然后,你可以在模板中使用ref
来获取插槽内元素的引用。
以下是一个示例代码:
<template> <slot name="trigger" ref="triggerRef" /> <teleport to="body"> <div v-if="show" class="absolute inset-0"> <slot ref="popoverContent" /> </div> </teleport></template><script setup>import { ref } from 'vue';const triggerRef = ref(null);const popoverContent = ref(null);</script>
在上面的代码中,我们在setup()
函数中创建了两个ref
:triggerRef
和popoverContent
。然后,我们将这两个ref
分别绑定到插槽元素上,通过在插槽标签上添加ref
属性并指定对应的引用名称。
现在,你可以通过triggerRef.value
和popoverContent.value
来访问插槽内元素的引用。注意,在使用引用时需要添加.value
来获取实际的值。
使用这种方法,你就不需要在触发元素和内容外套一层div来获取引用了。
问题内容: 我想替换html元素中的内容,所以为此使用了以下功能: 上面的方法效果很好,但是问题是我要替换其内容的页面上有多个html元素。因此,我不能使用id而是使用类。有人告诉我javascript不支持任何类型的内置get element by class函数。那么如何修改以上代码以使其与类(而不是ID)一起使用? PS我不想为此使用jQuery。 问题答案: 此代码应在所有浏览器中都有效。
vue3中,怎么获取子组件插槽内的DOM实例或者说ref? 我尝试这样获取,但是获取不到:
问题内容: 我一定在想这个错误。 我想在我使用Webdriver / Selenium 2访问的页面上获取元素的内容(在本例中为formfield) 这是我的损坏代码: 结果如下: (请注意空白行)我知道该元素包含内容,因为我只是使用.sendkeys使用先前的命令将它们填充在其中,并且在脚本运行时可以在实际的网页上看到它们。 但我需要将内容重新放入数据中。 我该怎么读?最好以通用方式,以便我可以
问题内容: 我正在寻找一种从样式标签中设置了样式的元素中检索样式的方法。 在身体里 我正在寻找不使用库的直接javascript。 我尝试了以下操作,但始终收到空白: 我注意到,如果我已使用javascript设置了样式,但无法使用样式标签,则只能使用以上内容。 问题答案: 该属性仅让您知道在该元素中定义为内联的CSS属性(以编程方式或在元素的style属性中定义),应该获取计算出的style。
我希望能够获取<template #loadMore>中 id为"is_load"的div元素 但是ref无法引用到 ,在onMounted函数中使用nextTick回调打印处理这个dom也是空的,等待渲染后也不行 有什么方法可以操作到dom vue 无法获取到template中的dom元素?
在调用这个组件的地方 接收childer组件作为插槽,在parent中 获取不到默认插槽的属性b,不知道为什么