简体   繁体   中英

Manually remove (and destroy) a component from keep-alive

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.

Unfortunately for you such functionality does not exists 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 inactivated hook which is called when kept-alive component is activated

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM