How to destroy a VueJS component that is being cached by

前端 未结 4 1525
天涯浪人
天涯浪人 2021-01-13 17:16

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

相关标签:
4条回答
  • 2021-01-13 17:47

    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.

    0 讨论(0)
  • 2021-01-13 17:53

    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.

    0 讨论(0)
  • 2021-01-13 17:59

    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>
    
    0 讨论(0)
  • 2021-01-13 18:10

    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();
        }
    });
    
    0 讨论(0)
提交回复
热议问题