1

In my vue app some particular components inrouter-view are cached by using <keep-alive></keep-alive> that vue provides.

When a user logs in the posts.vue component is cached as I said above

Everything works fine.

Now I want to destroy this posts.vue component when the user logs out.So that posts.vue component re-renders when the user logs in again

The log out button is present in completely other component menu.vue and the on click logic for log out is present in this nenu.vue component

So how could I implement this using vm.$destroy() method from menu.vue component on posts.vue component

so my main problem is how to control lifecycle of one component from the other

the docs warn using this as follows :,

In normal use cases you shouldn’t have to call this method yourself.

Prefer controlling the lifecycle of child components in a data-driven fashion using v-if and v-for.

but in my case I cant use v-if or v-show

or is there any better way i could use

tony19
  • 125,647
  • 18
  • 229
  • 307
boomboxboy
  • 2,384
  • 5
  • 21
  • 33

3 Answers3

1

When you log in or log out from child component, emit 'login' or 'logout' event respectively.

<template>
  <div id="app">
    <router-view name='login' @login="login=true"></router-view>
    <router-view name='header' @logout="login=false"></router-view>
    <keep-alive v-if="login">
      <router-view name='write'></router-view>
    </keep-alive>
    <router-view name='management'></router-view>
    <router-view name='account'></router-view>
    <router-view name='statistics'></router-view>
    <router-view name='view'></router-view>
    <router-view name='password'></router-view>
  </div>
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      login: true
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 0;
  height: 100%;
}
</style>
Jian Li
  • 320
  • 2
  • 6
0

I had similar problem and one simple solution I found was to force reload the web application via location.reload(), which clears the keep-alive.

You might also find this discussion interesting: https://github.com/vuejs/vue/issues/6259

loomchild
  • 748
  • 1
  • 8
  • 15
0

There is a pretty easy way to do this. Thanks to @loomchild for the link.

You can define on routes a meta object. Define it in such a way for routes using keep-alive that you want to invalidate.

    {
        path: '/invalidate_me',
        ...
        meta: {uuid: generateUUID()} // You'll need a method for this or something similar
    },

Check out Create GUID / UUID in JavaScript? for help with UUID if need be.

Then, in your keep alive definition:

      <router-view :key="$route.path + ($route.params.id ? $route.params.id : '').toString() + ($route.meta && $route.meta.uuid ? $route.meta.uuid.toString() : '')"></router-view>

Something like that. If you don't include ids or don't want to cache by those, fine. Those are not related to the question, but something that I am using. So you really only need the meta part. We're basically telling Vue to consider a component to be defined by the combination of the id on the route (if it exists) and the uuid on the route (if it exists)

Then, when you want to invalidate inside a component, change the uuid. You may need to find the route in the lists on $router, or if you're already inside the correct component, you can do:

this.$route.meta.uuid = generateUUID();

This gets a new uuid and clears the cache.

Hope this helps someone else!

Whelchel
  • 303
  • 2
  • 10