How to destroy a VueJS component that is being cached by <keep-alive>

这一生的挚爱 提交于 2019-12-01 11:22:32

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>

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!