Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue 2 <keep-alive> not working with <router-view> and key

I'm using vue-router with a series of components like tabs. Each <router-link> is a tab and the space below is the <router-view>. Two of the tabs are the same component with different filters, let's say they are products and the router adds a parameter for filtering: /products/new & /products/sale.

Inside of products are individual product components which get mounted when the route is opened. My problem is that when I switch between the routes, and the filter parameter is changed, the product components get remounted every time. I'd like to cache them so switching back and forth is easier. To do this I set up <keep-alive> and added :key='$route.fullPath' to my <router-view> but they don't seem to be cached. Each product is still firing a mounted() event when i switch between products.

<keep-alive>
  <router-view :key='$route.fullPath'></router-view>
</keep-alive>

Should I make each products view into a separate component?

like image 806
okwme Avatar asked Nov 30 '16 21:11

okwme


2 Answers

For use keep-alive with router view you should use unique key on view router like this:

 <keep-alive>
   <router-view :key="$route.fullPath"></router-view> 
 </keep-alive>

Dont forgot use max attribute on keep alive to prevent memory overhead

<keep-alive max="5">

or just include components want cache:

<keep-alive include="FirstComp,SecondComp"> 

And for each components inside component you need keep alive them if you want cache

<keep-alive>
  <product></product>
</keep-alive>
like image 176
Mohsen Avatar answered Sep 19 '22 06:09

Mohsen


Vue 3 - working example

When I tried solutions from above (in Vue 3) I got this in the console

[Vue Router warn]: <router-view> can no longer be used directly inside <transition> or <keep-alive>.
Use slot props instead:

<router-view v-slot="{ Component }">
  <keep-alive>
    <component :is="Component" />
  </keep-alive>
</router-view>

So I copied it into the App.vue like this...

// App.vue
...
  <router-view v-slot="{ Component }">
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </router-view>
...

And it works :)

like image 22
OziOcb Avatar answered Sep 22 '22 06:09

OziOcb