如何使用vue的keep-alive进行组件的前后台切换

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组件,我们就可以很容易地实现前后台切换而无需重复渲染组件,提升了效率。同时,通过使用不同的属性值,我们还可以根据路由进行缓存或根据组件状态进行操作。