1.什么是keep-alive
keep-alive是Vue提供的一个抽象组件,主要用于缓存组件。它可以将一个组件进行缓存,使得该组件在切换的时候,可以实现前后台切换而无需重复渲染。
在一个动态组件中,当组件被切换掉时,被销毁的组件会完全被移除掉。这也就意味着,当组件切换回来的时候,需要重新创建一个新的组件,再将其渲染出来。这种逻辑对于一些经常被使用的组件来说,效率是非常低下的。而keep-alive则可以将组件进行缓存,保留状态,当组件再次被使用时,就可以直接从缓存中取出,而无需重新进行渲染等耗费时间的操作。
2.keep-alive的使用
2.1 keep-alive的基本应用
在Vue中,通过在组件包裹外层加入一个<keep-alive>标签,即可对该组件进行缓存:
<keep-alive>
<component :is="currentTab"></component>
</keep-alive>
其中,<component :is="currentTab"></component>就是我们需要进行缓存的组件。
这里需要注意的是,由于keep-alive是抽象组件,因此无论我们在组件的data中,还是在props中定义一个名为keep-alive的值,都会被忽略掉。
使用keep-alive缓存组件后,我们还可以通过beforeRouteLeave来离开页面前进行一些操作。
beforeRouteLeave (to, from, next) {
const keepAliveComponents = this.$refs.keepAlive.$children
for(let i=0; i<keepAliveComponents.length; i++) {
keepAliveComponents[i].$emit('beforeLeave')
}
next()
}
需要注意的是,在进行缓存的同时,组件生命周期中的mounted钩子并不会被调用,而是通过activated钩子进行调用。
2.2.根据路由进行缓存
keep-alive还提供了一个include属性,允许我们根据路由或者组件名进行缓存。例如,我们可以在App.vue组件中对于不同的路由做出不同的缓存策略:
<template>
<div id="app">
<keep-alive :include="cachedViews">
<router-view></router-view>
</keep-alive>
</div>
</template>
<script>
export default {
data() {
return {
cachedViews: [] // 需要缓存的页面名称
}
},
watch: {
$route(to, from) {
const { name } = to
const { name: oldName } = from
const cachedViews = this.cachedViews
if(oldName) {
const index = cachedViews.indexOf(oldName)
if(index > -1) {
cachedViews.splice(index, 1)
}
}
if(name && !cachedViews.includes(name)) {
cachedViews.push(name)
}
}
}
}
</script>
在这里,我们通过include属性来指定需要缓存的组件,而cachedViews则表示需要缓存的组件名。因此,每次页面之间路由进行切换的时候,我们就可以根据$route来判断是否需要缓存当前的组件。
2.3.根据keep-alive缓存状态进行操作
在keep-alive缓存的组件中,Vue为我们提供了activated和deactivated两个事件。这两个事件分别在组件被激活和组件被销毁的时候被触发。因此,我们可以利用这两个事件来进行更加细致的控制,例如:
<template>
<div>
<button @click="startCount">开始计数</button>
<button @click="stopCount">停止计数</button>
<p>当前计数:{{ counter }}</p>
</div>
</template>
<script>
let timer = null
export default {
name: 'Count',
data() {
return {
counter: 0
}
},
activated() {
this.startCount()
},
deactivated() {
this.stopCount()
},
methods: {
startCount() {
timer = setInterval(()=> {
this.counter++
}, 1000)
},
stopCount() {
clearInterval(timer)
}
}
}
</script>
在这里,我们通过activated和deactivated方法分别在组件被激活和销毁的时候,分别进行了计时器的开启和关闭。这样就可以保证在组件被缓存、刷新、重新渲染之间,计时器始终处于正确的状态。
3.总结
通过使用Vue提供的keep-alive组件,我们就可以很容易地实现前后台切换而无需重复渲染组件,提升了效率。同时,通过使用不同的属性值,我们还可以根据路由进行缓存或根据组件状态进行操作。