0

I have a navigation bar component with a variable width in the following format:

    <template>
      <div class="container">
         <div v-if="!!$scopedSlots.menu">
          <slot name="menu" />
         </div>
         ...
      </div>
    </template>

I am creating a new component that can be slotted in to that "menu" slot which should function as a button that opens a dropdown the width of the entire nav bar.

Is there a good way to reactively monitor the width of that container from within the child component? I am able to get its initial width in mounted() like so:

this.parentWidth = (this.$parent.$parent.$el as HTMLElement).offsetWidth;

This only gets me the initial width of that element though. If its container grows the child component will not grow reactively. I've tried changing this assignment to a computed value but I can't access the parent element when the page is rendered and the styles computed comes back undefined or in the case below with width: 'auto' no matter what:

computed: {
   styles() {
     const parent = this.$parent.$parent.$el as HTMLElement;
     if(!!parent) {
        return {width: `${parent.offsetWidth}px`};
     } else {
        return {width: 'auto'};
     }
   }
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
Tom Kaizer
  • 80
  • 10
  • Seems like this is just a matter of good CSS. Flexbox provides this behavior with no scripting. I'd start from a rendered example and translate solutions to your React components. Could you show us that? – isherwood Mar 24 '22 at 19:25
  • Or is the dropdown an entirely separate structure? – isherwood Mar 24 '22 at 19:27
  • The nav-bar is a preexisting component with a `menu` slot that simply handles formatting the location of an icon button. This new component is completely separate. Its intended use is specifically within this nav-bar component though – Tom Kaizer Mar 24 '22 at 19:34
  • I don't think that changes my position. The navbar can control how child components are rendered with just CSS to some extent. That's why I think it would be helpful to see the rendered HTML. – isherwood Mar 24 '22 at 19:38

1 Answers1

0

Found a solution that worked here looks like there isn't an ideal solution with Vue alone. I needed to use ResizeObserver.

Tom Kaizer
  • 80
  • 10