如何销毁 <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 组件的主要内容,如果未能解决你的问题,请参考以下文章