简体   繁体   English

如何销毁正在缓存的 VueJS 组件<keep-alive>

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

I have a Vue component that's kept alive using Vue's element for caching purposes.我有一个 Vue 组件,它使用 Vue 的元素保持活动状态以进行缓存。 However, the problem I am having right now is that once I sign out of one account and create a new account on my Vue application, the component I'm "keeping alive" is being reflected for the new user (which obviously isn't relevant for the new user).但是,我现在遇到的问题是,一旦我注销一个帐户并在我的 Vue 应用程序上创建一个新帐户,我“保持活动”的组件就会反映给新用户(这显然不是与新用户相关)。

As a result, I want to destroy that component once the user signs out.因此,我想在用户退出后销毁该组件。 What is the best way to go about this?解决这个问题的最佳方法是什么?

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:这是我的 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() 生命周期中所做的:

   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另一个.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.但是总线事件是我做到这一点的方式,你可以使用你想要的一切,比如子发射器或 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.您所要做的就是在阵列中添加或删除您的组件。

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在我的情况下,我在注销路由中使用它,在 Vue 实例中将 router.app 替换为 this.$root 并且 $children 索引/嵌套可能因您的应用程序而异

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();
    }
});

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/见: 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.您需要在您的组件上实现 reset 方法,并在用户注销或新用户登录时以编程方式调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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