[Solved by @metalsadman] How to store data in nested v-for loops for q-expansion-items?



  • I have built a directory for help information. It is based on a nested Javascript datastructure that represents the help information. Every help topics consists of a (DOM) id, label text, and possibly an icon. The ids are passed to my help component as scroll targets, as part of router links. Help topics can have other help topics as children.

    Here is my test directory for that help information (3 levels deep):

    {
        id: "2.0",
        überschrift: "Bauvorhaben",
        icon: "img:statics/icons/Bauvorhaben-Icon.svg",
        unterVerzeichnis: [
          {
            id: "2.1",
            überschrift: "Was ist das?"
          },
          {
            id: "2.2",
            überschrift: "Eigenschaften"
          },
          {
            id: "2.3",
            überschrift: "Vererbung"
          },
          {
            id: "2.4",
            überschrift: "Bedienung"
          }
        ]
      },
      {
        id: "3.0",
        überschrift: "Baustoffe",
        icon: "img:statics/icons/Baustoffe-Icon.svg",
        unterVerzeichnis: [
          {
            id: "3.1",
            überschrift: "Was ist das?"
          },
          {
            id: "3.2",
            überschrift: "Eigenschaften"
          },
          {
            id: "3.3",
            überschrift: "Vererbung",
            unterVerzeichnis: [
              {
                id: "3.3.1",
                überschrift: "Vererbungsprinzip"
              }
            ]
          },
          {
            id: "3.4",
            überschrift: "Bedienung"
          }
        ]
      },
    
      {
        id: "4.0",
        überschrift: "Bauinformationen",
        icon: "img:statics/icons/Bauvorschriften-Icon.svg"
      },
      {
        id: "5.0",
        überschrift: "Validierung/Optimierung",
        icon: "img:statics/icons/Verschiedenes-Icon.svg"
      },
      {
        id: "6.0",
        überschrift: "Datenaustausch",
        icon: "img:statics/icons/Verschiedenes-Icon.svg"
      },
      {
        id: "7.0",
        überschrift: "Einstellungen",
        icon: "img:statics/icons/Verschiedenes-Icon.svg"
      },
      {
        id: "8.0",
        überschrift: "Glossar",
        icon: "img:statics/icons/Verschiedenes-Icon.svg"
      }
    ];
    

    I’m displaying this directory through Quasar q-expansion items. I have 3 nested v-fors that traverse the help directory, and create nested q-expansion items from it:

            <div
              v-for="hilfeThemaEbene1 in this.hilfeVerzeichnis"
              :key="hilfeThemaEbene1.id"
            >
              <q-expansion-item
                expand-icon-toggle
                expand-separator
                default-opened
                dense
                group="accordeon-group-1"
                header-class="bg-teal text-white"
                :header-inset-level="0"
                :icon="hilfeThemaEbene1.icon"
                :label="hilfeThemaEbene1.id + ' ' + hilfeThemaEbene1.überschrift"
                :label-lines="1"
                :to="'/Hilfe/' + hilfeThemaEbene1.id"
              >
                <div
                  v-for="hilfeThemaEbene2 in hilfeThemaEbene1.unterVerzeichnis"
                  :key="hilfeThemaEbene2.id"
                >
                  <q-expansion-item
                    expand-icon-toggle
                    expand-separator
                    default-opened
                    dense
                    group="accordeon-group-2"
                    header-class="bg-teal-3 text-black"
                    :header-inset-level="0.4"
                    :label="
                      hilfeThemaEbene2.id + ' ' + hilfeThemaEbene2.überschrift
                    "
                    :label-lines="1"
                    :to="'/Hilfe/' + hilfeThemaEbene2.id"
                  >
                    <div
                      v-for="hilfeThemaEbene3 in hilfeThemaEbene2.unterVerzeichnis"
                      :key="hilfeThemaEbene3.id"
                    >
                      <q-expansion-item
                        expand-icon-toggle
                        expand-separator
                        default-opened
                        dense
                        group="accordeon-group-3"
                        header-class="bg-teal-1 text-black"
                        :header-inset-level="0.8"
                        :label="
                          hilfeThemaEbene3.id + ' ' + hilfeThemaEbene3.überschrift
                        "
                        :label-lines="1"
                        :to="'/Hilfe/' + hilfeThemaEbene3.id"
                      >
                      </q-expansion-item>
                    </div>
                  </q-expansion-item>
                </div>
              </q-expansion-item>
            </div>
    

    The result looks nice, and the users are able to click on/select a help topic in one of the expansion items which then invokes the help component through the :to router links, which passes the DOM id to be scrolled to for the selected help topic, as part of the route and as a property to the help component:

    6843b9b8-ec8b-4ffe-b208-2f931148ccec-image.png

    The small remaining challenge that I have is probably more a Vue than a Quasar question:
    In the above v-fors and q-expansion-items, how can I store the value of the selected id (this is either hilfeThemaEbene1.id, or hilfeThemaEbene2.id, or hilfeThemaEbene3.id) in a regular variable? I need the id of the selected item for other purposes. This is easy with @input events, where I can call a method with the id as an input parameter, but I’m lost how to do this with the above expansion items, where the only action, if clicking at the item, seems to be the :to router link. The router link even contains the id, but how do I get that copied into some variable in data()?



  • @Mickey58 you can use @click="someDummyVar = someData", if you need the data in the target route you set in your :to you can pass it as a prop like so :to="{ name: 'routeName', params: { data: someData } }" (you need to name your route if doing this way). https://router.vuejs.org/guide/essentials/passing-props.html



  • Thanks @metalsadman, glad to see it is that simple. The q-expansion-item doc would deserve a hint that q-expansion-items support (of course…) @click events,. Anyway, I put additional @click events to my q-expansion items as you suggested, e.g.

    @click="selectedHelpTopicId = hilfeThemaEbene1.id"
    

    That works perfectly together with a watcher on route changes that I have set up in my help component, which indirectly uses the ids stored in those @click events in the myLayout/drawer component.

    My challenge was to get this working both through the above selections of expansion items in the help directory, and if the user switches to the help component through clicking on the “help” tab in my main menu at the top of the app. In that latter case the help scrolls now also to the last help topic selected.

    Perfect solution, thanks a lot.


Log in to reply