Subscribe on changes!

Get width of slot from useSlot()

avatar
Sep 23rd 2022

Vue version

3.2

Link to minimal reproduction

https://sfc.vuejs.org/#eNp9U9uO00AM/RUrPGwipQm8lrYC8Qkg8cDwkKbOdpa5aWaSLqry79iTzNLCavNSX46PfTzutfjsXDONWGyLXei9dBECxtEdhJHaWR/hi9UOBm81PDQtOwx/EGbXLnhCkhNRO9VFZC/uGEYWANk5A+8iBkYDfRR3EOJvhXtRHK0/od/CB/cMwSp5gqMaURQrlj9lPWqQLow6B3ft0oKtm+7sLu0jz/iSKepiEbTRnWuegjUk+ZpmXBNBFFtIEY6RSPZFcY7RhW3bhqFn5U+hsf6xJavxo4lSY4NBb47eXgJ6IhZFfcPRUnBCv/FoSCP6tzj/gf7Hy7SzMDNJye/Az3a/+pOc8lqOY4zWwCdtx4CWqGnXIRKyCWd7gT1EzyJXgMJu4te4QwydCrcvcWYa0JgXv7TIDak3TBs53LGkahETICgbwXSa+/A1UI7OiIKHhT7TZhHZunthcl+/1Ct47PooJ6zh0sX+XAPp+kr0oQaDz/Gb7H/BvB7zcsXC9NYEomIUCc4FZfXxJcVSKJXJy3QjLG277sfMFc8uTOpalhXsD0tZ2kANSyTVyQHKv6kqH1weby1eowA8glXYKPtYphkb3ltZ/Xj/s0HV2GGgJXyXp3iulpI5/fKZJOPmf1rMfwD55lHB

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?

Playground with above example

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

avatar
Sep 23rd 2022

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.