Home > Back-end >  Manually remove (and destroy) a component from keep-alive
Manually remove (and destroy) a component from keep-alive

Time:11-26

I can't find how to get access to a component instance loaded from Vue Route, and persisted by means of <keep-alive> and <component>, so that I can programmatically unmount it.

I'm implementing a dynamic tab system so that each tab renders a URL, which in turn displays its declared component. I don't want to unmount a component everytime I load a new route whenever I create a new tab, or select another tab. I achieved it by combining with keep-alive/component in a custom component called MultiTabs:

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

So far so good. Let's say I've got these routes:

//...
{
   path: '/foo',
   name: 'Foo',
   component: () => import("./components/pages/Foo.vue"),
},
{
   path: '/bar',
   name: 'Bar',
   component: () => import("./components/pages/Bar.vue"),
},
//...

router.beforeEach((to, from, next) => {
   store.dispatch('addTab', to); // --> Vuex would then add this route to a list of tabs (routes), which I will retrieve from the MultiTabs component.
   next();
});

From my MultiTabs component, I get all the tabs (queried routes), and display them, as the tabs navigation, and the component that should be rendered:

MultiTabs.vue:

<template>
   <!-- ... -->
   <!-- MultiTab has a close button which emits the tabClosed event  -->
   <multi-tab 
      v-for="route of storedTabs" 
      :key="route.fullPath" 
      :route="route" 
      @selectedRoute="selectRoute" 
      @tabClosed="closeTab"
      >
   </multi-tab>
   <!-- ... -->
   <!-- This is where the component for the selected route is rendered -->
   <div class="tab-pane">
      <slot/>
   </div>
</template>

So, when the user clicks on the close button in a tab, I want to free the corresponding component from memory. Note that this won't happen navigating through tabs because I used keep-alive and want this behaviour, so that the component is not mounted again and it performs the async calls to the server again.

CodePudding user response:

Unfortunately for you such functionality does not exist yet. There are few issues in Vue repo including this one where you can find a hacky sample how to do that but it uses some internal details so using it might be risky as those details can change anytime...

Here is a ongoing discussion/RFC so if you need this, feel free to engage in the discussion or vote

Until the mentioned functionality is implemented, your best option is probably to refactor your components and do what you need to do not only in created/mounted hooks but also in activated hook which is called when kept-alive component is activated

  • Related