I have a Vue component that\'s kept alive using Vue\'s element for caching purposes. However, the problem I am having right now is that once I sign out of one account and c
I had the same problem and I solved it by using an array of cached components and bus event.
Here is my HTML keep-alive
App.vue:
<keep-alive :include="cachedComponents">
<router-view></router-view>
</keep-alive>
Here is what I'm doing in the created() life cycle:
created() {
// Push Home component in cached component array if it doesn't exist in the array
if (!this.cachedComponents.includes('Home')) {
this.cachedComponents.push('Home')
}
// Event to remove the components from the cache
bus.$on('clearCachedComponents', (data) => {
// If the received component exist
if (this.cachedComponents.includes(data)) {
// Get the index of the component in the array
const index = this.cachedComponents.indexOf(data)
// Remove it from the array
this.cachedComponents.splice(index, 1)
}
})
}
And inside another component just trigger the event and send the component to remove in parameter.
Another.vue
bus.$emit('clearCachedComponents', 'Home')
If you don't know how to make a bus event there are lot of tutorials on the internet like this to do that. But bus event is my way to do that and you can use everything you want like a child emitter or Vuex. That I want to show is to use an array of components to manage your cache. All you have to do is to add or remove your components in the array.
If your problem is that the component is still holding the old user's data, the only option is resetting it with an internal reset function, which reloads the data for the new user one way or another.
See: http://jsfiddle.net/paolomioni/hayskdy8/
var Home = Vue.component('Home', {
template: `<div><h1>{{ title }}</h1>
<input type="button" value="click to change text" v-on:click="title = Math.random()"">
<input type="button" value="click to reset component" v-on:click="reset"></div>`,
data: () => {
return {
title: 'BBB'
}
},
methods: {
reset() {
this.title = 'BBB'
}
}
});
In the fiddle, click on the button "change text" to change the text: if you click the checkbox twice to switch view and back again, you will see that the number you've generated is still kept in memory. If you click on the "reset" button, it will be reset to its initial state. You need to implement the reset method on your component and call it programmaticaly when the user logs out or when the new user logs in.
I've managed to solve my issue in the following way. Essentially, if the user is logged in, keep the dashboard alive. Else, don't keep the dashboard alive. I check if the user is logged in or out every time the route changes by "watching" the route (see below). If you are reading this and have a more elegant solution - I'd love to hear it.
The following is the code for my root component
<template>
<div id="app">
<!-- if user is logged in, keep dashboard alive -->
<keep-alive
v-bind:include="[ 'dashboard' ]"
v-if="isLoggedIn">
<router-view></router-view>
</keep-alive>
<!-- otherwise don't keep anything alive -->
<router-view v-else></router-view>
</div>
</template>
<script>
import firebase from "firebase";
export default {
name: 'app',
data() {
return {
isLoggedIn: false // determines if dashboard is kept alive or not
}
},
watch: {
$route (to, from){ // if the route changes...
if (firebase.auth().currentUser) { // firebase returns null if user logged out
this.isLoggedIn = true;
} else {
this.isLoggedIn = false;
}
}
}
}
</script>
for anyone looking for a solution that destroys the cache
in my case I was using this in a logout route, replace router.app with this.$root in Vue instances and the $children index/nesting may differ for your app
setTimeout(() => {
var d = [];
for(var vm of router.app.$children[0].$children) {
if(vm._inactive === true)
d.push(vm);
}
for(var vm of d) {
vm.$destroy();
}
});