如何销毁被 <keep-alive> 缓存的 VueJS 组件
How to destroy a VueJS component that is being cached by <keep-alive>
我有一个 Vue 组件,它使用 Vue 的元素保持活动状态以进行缓存。但是,我现在遇到的问题是,一旦我退出一个帐户并在我的 Vue 应用程序上创建一个新帐户,我 "keeping alive" 的组件就会反映给新用户(这显然不是' t 与新用户相关)。
因此,我想在用户注销后销毁该组件。解决此问题的最佳方法是什么?
如果您的问题是该组件仍然保存着旧用户的数据,唯一的选择是使用内部重置功能对其进行重置,这会以某种方式为新用户重新加载数据。
参见:
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'
}
}
});
在 fiddle 中,单击按钮 "change text" 更改文本:如果您单击复选框两次切换视图并再次返回,您将看到您生成的数字仍然保留在记忆中。如果单击 "reset" 按钮,它将重置为初始状态。您需要在您的组件上实现重置方法,并在用户注销或新用户登录时以编程方式调用它。
我已经通过以下方式解决了我的问题。本质上,如果用户已登录,则让仪表板保持活动状态。否则,不要让仪表板保持活动状态。每次路线更改 "watching" 路线时,我都会检查用户是否登录或注销(见下文)。如果您正在阅读这篇文章并且有更优雅的解决方案 - 我很乐意听到它。
下面是我的根组件的代码
<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>
我遇到了同样的问题,我通过使用缓存组件数组和总线事件解决了它。
这是我的 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)
}
})
}
并且在另一个组件内部触发事件并发送组件以在参数中移除。
Another.vue
bus.$emit('clearCachedComponents', 'Home')
如果您不知道如何制作巴士活动,可以在互联网上找到很多教程,例如 this。但总线事件是我这样做的方式,你可以使用任何你想要的东西,比如子发射器或 Vuex。我想展示的是使用一组组件来管理您的缓存。您所要做的就是在数组中添加或删除组件。
对于正在寻找破坏缓存的解决方案的任何人
在我的例子中,我在注销路由中使用了它,将 router.app 替换为 this.$root 在 Vue 实例中,$children index/nesting 可能因您的应用程序而异
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();
}
});
我有一个 Vue 组件,它使用 Vue 的元素保持活动状态以进行缓存。但是,我现在遇到的问题是,一旦我退出一个帐户并在我的 Vue 应用程序上创建一个新帐户,我 "keeping alive" 的组件就会反映给新用户(这显然不是' t 与新用户相关)。
因此,我想在用户注销后销毁该组件。解决此问题的最佳方法是什么?
如果您的问题是该组件仍然保存着旧用户的数据,唯一的选择是使用内部重置功能对其进行重置,这会以某种方式为新用户重新加载数据。
参见: 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'
}
}
});
在 fiddle 中,单击按钮 "change text" 更改文本:如果您单击复选框两次切换视图并再次返回,您将看到您生成的数字仍然保留在记忆中。如果单击 "reset" 按钮,它将重置为初始状态。您需要在您的组件上实现重置方法,并在用户注销或新用户登录时以编程方式调用它。
我已经通过以下方式解决了我的问题。本质上,如果用户已登录,则让仪表板保持活动状态。否则,不要让仪表板保持活动状态。每次路线更改 "watching" 路线时,我都会检查用户是否登录或注销(见下文)。如果您正在阅读这篇文章并且有更优雅的解决方案 - 我很乐意听到它。
下面是我的根组件的代码
<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>
我遇到了同样的问题,我通过使用缓存组件数组和总线事件解决了它。
这是我的 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)
}
})
}
并且在另一个组件内部触发事件并发送组件以在参数中移除。
Another.vue
bus.$emit('clearCachedComponents', 'Home')
如果您不知道如何制作巴士活动,可以在互联网上找到很多教程,例如 this。但总线事件是我这样做的方式,你可以使用任何你想要的东西,比如子发射器或 Vuex。我想展示的是使用一组组件来管理您的缓存。您所要做的就是在数组中添加或删除组件。
对于正在寻找破坏缓存的解决方案的任何人
在我的例子中,我在注销路由中使用了它,将 router.app 替换为 this.$root 在 Vue 实例中,$children index/nesting 可能因您的应用程序而异
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();
}
});