Help with q-route-tabs & q-tab-panels using keep-alive and router-views



  • Hi all, I’m struggling to get these q-tabs and panels working how I want. What I want: tab should be mounted when first viewed, and then not mounted again until the parent route changes. What I’m getting: tab mounted is called every time I change tabs. My app code is obviously more complex, but I made a code sandbox to demo where I’m stuck. https://codesandbox.io/s/codesandbox-app-forked-yd7su Click the “Directory” link to view the tabs, then watch the console as each tab mounted is called when the tabs are changed.

    Here’s my tabs code:

    <q-tabs inverted color="secondary" narrow-indicator class="bg-grey-3" dense>
            <q-route-tab name="general" replace :to="{name: 'directory-view'}" label="General"/>
            <q-route-tab name="addresses" replace :to="{name: 'directory-addresses'}" label="Addresses" />
            <q-route-tab name="history" replace :to="{name: 'directory-history'}" label="History"/>
          </q-tabs>
          <q-tab-panels v-model="tab" animated keep-alive>
            <q-tab-panel name="general">
              <router-view/>
            </q-tab-panel>
            <q-tab-panel name="addresses">
              <router-view/>
            </q-tab-panel>
            <q-tab-panel name="history">
              <router-view/>
            </q-tab-panel>
          </q-tab-panels>
    

    What am I missing? Do I have the keep-alive attribute in the right place? I’ve tried adding keys, wrapping the router-views in Vue keep-alive tags, etc. and nothing seems to work like I expect. Help please!



  • @geeky you don’t need to use panels if you are using a qroutetabs. Just have one router-view and wrap it in a keep-alive tag. Like this https://quasar.dev/vue-components/tabs#Connecting-to-Vue-Router.



  • @metalsadman Thanks! That makes a lot of sense looking at my simplified example. However, I used the router-views in q-tab-panels set up (found via another forum question) because each tab has it’s own component that I need to pass props and assign event handlers to. I don’t suppose there’s a way to do that with a single router-view?



  • @geeky you can pass props in router, or if you want to opt for q-tab-panels still, just import your panel components in your parent tab and use it is as local components.



  • @metalsadman pretty sure passing props in the router won’t work for me - they’re dynamic bound props. Can you elaborate on what you mean by this: “import your panel components in your parent tab and use it is as local components”? I originally had this set up and working with q-tabs and q-tab-panels with components inside each q-tab-panel - and it worked great! I only changed it to using q-route-tabs because I want to use the router to get a URL change on tab change / direct link to each tab.



  • Here’s a more accurate example of what my tab panels look like in my project right now (names changed to keep it generic):

     <q-tab-panels v-model="tab" animated keep-alive>
         <q-tab-panel name="general" class="overflow-hidden">
             <router-view
                 @tabResponse="onTabResponse"
                 @tabChange="onTabChange"
                 :prop1="object1"
                 :prop2="object2"
                 :prop3="booleanvalue"
               />
         </q-tab-panel>
         <q-tab-panel name="history" class="overflow-hidden" >
             <router-view
               :prop1="object1"
               :prop2="booleanvalue"
             />
         </q-tab-panel>
    
    ... etc
    
    </q-tab-panels>
    

    In summary: All of this works, EXCEPT for the keep-alive. I would love to use q-route-tabs to get a unique URL for each tab, each tab panel has a unique component that may needs props and/or event handlers, and I would also love to have keep-alive work so that my components aren’t re-rendered whenever tabs are changed (they should only re-render when the parent component parameters change).

    If there’s a better/different way to accomplish what I’m trying to do, I’m open to it. Thanks!



  • @tsulli Looking for the same solution, no idea how to get Keep Alive work router-view

    the only way to get it work is, wrap another keep-alive each q-tab-panel, but it create a lot of duplicated component

        <q-tab-panels v-model="tab" animated keep-alive>
          <q-tab-panel name="bookmark"><keep-alive><router-view /></keep-alive></q-tab-panel>
          <q-tab-panel name="property"><keep-alive><router-view /></keep-alive></q-tab-panel>
          <q-tab-panel name="message"><keep-alive><router-view /></keep-alive></q-tab-panel>
        </q-tab-panels>
    


  • maybe this will help:

    https://vuejs.org/v2/api/#keep-alive



  • @altezzalab Thanks! I can verify that does seem to work. Feels pretty wrong, but since it works we’ll go with that for now.


Log in to reply