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

Posted

技术标签:

【中文标题】如何销毁 <keep-alive> 缓存的 VueJS 组件【英文标题】:How to destroy a VueJS component that is being cached by <keep-alive> 【发布时间】:2018-07-17 14:42:22 【问题描述】:

我有一个 Vue 组件,它使用 Vue 的元素进行缓存以保持活动状态。但是,我现在遇到的问题是,一旦我退出一个帐户并在我的 Vue 应用程序上创建一个新帐户,我正在“保持活动状态”的组件就会反映给新用户(这显然不是与新用户相关)。

因此,我想在用户退出后销毁该组件。解决此问题的最佳方法是什么?

【问题讨论】:

也许包含/排除可以帮助? vuejs.org/v2/api/#keep-alive 感谢您的建议,但我相信包含/排除用于有条件地选择组件以保持活动状态。我的问题更多与销毁用户注销时保持活动状态的组件有关,以便在我创建新帐户时不会对其进行缓存。 【参考方案1】:

我已经设法通过以下方式解决了我的问题。本质上,如果用户已登录,则保持仪表板处于活动状态。否则,不要让仪表板保持活动状态。每次路线更改时,我都会通过“观察”路线检查用户是否登录或退出(见下文)。如果您正在阅读本文并有更优雅的解决方案 - 我很乐意听到。

以下是我的根组件的代码

<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>

【讨论】:

【参考方案2】:

我遇到了同样的问题,我通过使用缓存组件数组和总线事件解决了这个问题。

这是我的 html keep-alive App.vue:

<keep-alive :include="cachedComponents">
  <router-view></router-view>
</keep-alive>

这是我在 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)
        
      )
    

而在另一个组件内部只是触发事件并将组件发送到参数中删除。

另一个.vue

bus.$emit('clearCachedComponents', 'Home')

如果您不知道如何制作巴士活动,互联网上有很多教程,例如 this。但是总线事件是我的方法,你可以使用任何你想要的东西,比如子发射器或 Vuex。我想展示的是使用一组组件来管理您的缓存。您所要做的就是在阵列中添加或删除您的组件。

【讨论】:

【参考方案3】:

对于任何寻求破坏缓存的解决方案的人

在我的情况下,我在注销路由中使用它,在 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();
    
);

【讨论】:

【参考方案4】:

如果您的问题是组件仍在保存旧用户的数据,则唯一的选择是使用内部重置功能对其进行重置,该功能会以一种或另一种方式为新用户重新加载数据。

见: 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'
    
  
);

在小提琴中,单击“更改文本”按钮以更改文本:如果单击两次复选框以切换视图并再次返回,您将看到您生成的数字仍然保留在内存中。如果单击“重置”按钮,它将重置为初始状态。您需要在组件上实现 reset 方法,并在用户注销或新用户登录时以编程方式调用它。

【讨论】:

感谢您的建议,但我想我可能已经找到了一种更直接的方法来实现我的需要。请参考我对这篇文章的回答,让我知道你的想法:) 你的解决方案更直接,是的。

以上是关于如何销毁 <keep-alive> 缓存的 VueJS 组件的主要内容,如果未能解决你的问题,请参考以下文章

如何销毁/卸载 vue.js 3 组件?

Vue keep-alive

Vue keep-alive 总结

vue的keep-alive

vue中keep-alive路由缓存

vue的keep-alive