Opening QCollapsible when a route is matched to one of its items.



  • Regarding Vue Router and Layout integration, how can I dynamically open a QCollapsible that contains the QSideLink with linkExactActiveClass when a route is visited, given I have multiple collapsibles?
    e.g.

    <template>
      <div v-for="link in formattedLinks">
        <q-collapsible v-if="link.isCollapsible" v-bind="link">
          <q-side-link
            item
            exact
            v-for="sublink in link.sublinks"
            v-bind="sublink"
          />
        </q-collapsible>
        ...
      </div>
    </template>
    <script>
    export default {
      name: 'SidebarNavigation',
      ...
      props: {
        link: {
          type: Array,
          required: true,
          ...
        }
      }
    }
    </script>
    

    I was able to create a workaround but I really don’t like it…

    ...
    methods: {
      openActiveCollapsible() {
        // :( 
        const activeCollapsible = this.$el.querySelector(this.linkExactActiveClass);
        
        if (!activeCollapsible) {
          return;
        }
    
        activeCollapsible.parentElement.parentElement.parentElement.firstElementChild.click();
      }
    mounted() {
      this.openActiveCollapsible();
    }
    

    I’m thinking if I should check for the existence of the linkExactActiveClass, or compare the current route with the QSideLink:to and trigger open method of the parent ref.
    Does anyone have an idea on how to do this properly?



  • Another approach: use route meta:

    // route definition in router.js
    {
      path: 'path',
      component: ParentComponent,
      meta: {
        parent: 'ParentName'
      },
      chilldren: [
        {
          path: 'child',
          component: ChildComponent,
          meta: {
            parent: 'ParentName'
          }
        }
      ]
    }
    // usage in component
    this.$route.meta.parent === 'ParentName' // parent matches
    


  • I got it working using events and wrapping <q-side-link> to emit an event when exactActiveClass is present.

    <!-- link.group is a unique string -->
    <q-collapsible :ref="link.group" v-if="link.isCollapsible" v-bind="link">
      <sidebar-navigation-item
        item
        exact
        v-for="sublink in link.sublinks"
        v-bind="sublink"
        :parent-ref="link.group"
        @active="openActiveCollapsible"
      />
    </q-collapsible>
    ...
    methods: {
      openActiveCollapsible(ref) {
        this.$refs[ref][0].open()
      }
    }
    // in <sidebar-navigation-item>
    mounted() {
      if (this.$el.classList.contains(this.exactActiveClass)) {
        this.$emit('active', this.parentRef);
      }
    }