Get width of slot from useSlot()
Vue version
3.2
Link to minimal reproduction
Steps to reproduce
I'm getting the width of the HTML element which is passed as slot like this:
<template>
<div>
<button @mouseover="state.show = true" @mouseleave="state.show = false">
hover me
</button>
<div v-if="state.show">
<slot name="test"></slot>
</div>
</div>
</template>
<script setup>
import { reactive, watch, useSlots, nextTick } from 'vue'
const slots = useSlots();
const state = reactive({
show: false
})
watch(() => state.show, () => {
if (state.show) {
nextTick(() => {
console.log(slots.test()[0].el.offsetWidth)
})
}
})
</script>
This print correct value only on first hover of button. When hovered more than one time, it logs 0
. Why? How to get width of <slot name="test"></slot>
every time I hover button?
I also tried with getBoundingClientRect()
on onUpdated
vue hook which is executed after DOM changes:
<script setup>
import { reactive, watch, useSlots, nextTick, onUpdated } from 'vue'
const slots = useSlots();
const state = reactive({
show: false
})
onUpdated(() => {
if (state.show && slots.test() && slots.test()[0] && slots.test()[0].el) {
console.log(slots.test()[0].el.getBoundingClientRect())
}
})
</script>
With the same result - it shows correct width only on first hover. Playground with this example
What is expected?
Show width of the slot everytime I hover button
What is actually happening?
Width of the slot is visible only one time after that when hover button more than one time it's always 0
System Info
Any system, any browser
Any additional comments?
No response
calling a slot function does not give you the same vnodes as the ones created while the slot is being rendered.
So useSlots
cannot directly give you access to the elements created for a slot's vnodes. Please use Discord or the repo discussions to ask for help regarding your challenge. But this is not a bug.