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

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

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

【问题讨论】:

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

标签: javascript vue.js vue-component vue-router


【解决方案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 方法,并在用户注销或新用户登录时以编程方式调用它。

        【讨论】:

        • 感谢您的建议,但我想我可能已经找到了一种更直接的方法来实现我的需要。请参考我对这篇文章的回答,让我知道你的想法:)
        • 你的解决方案更直接,是的。
        猜你喜欢
        • 2019-12-16
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        • 2018-07-08
        • 2018-04-03
        • 2018-12-18
        • 2018-05-13
        • 2017-11-30
        相关资源
        最近更新 更多