一、keep-alive概念
1、概念
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition>
相似,<keep-alive>
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。
2、理解
主要用于保留组件状态或避免重新渲染。(让不展示的路由组件保持挂载,不被销毁)
默认情况下,在切换路由时,不展示的组件会被销毁掉,每次切换路由都是一次重新挂载
3、用法
<keep-alive>
<router-view></router-view>
</keep-alive>
4、配置项
① include
include - 字符串或正则表达式,只有名称匹配的组件才会被缓存
include = "Cats"
名称是Cats的路由组件会被缓存
<!-- 逗号分隔字符串 -->
<keep-alive include="Cats,Dogs"> //Cats和Dogs组件都缓存
<router-view></router-view>
</keep-alive>
<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/Cats|Dogs/"> //Cats和Dogs组件都缓存
<router-view></router-view>
</keep-alive>
<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['Cats', 'Dogs']"> //Cats和Dogs组件都缓存
<router-view></router-view>
</keep-alive>
匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。
② exclude
exclude - 字符串或正则表达式,任何名称匹配的组件都不会被缓存
。
exclude = "Cats"
名称是Cats的路由组件不会被缓存
③ max (2.5.0新增)
max - 数字。最多可以缓存多少组件实例。
部分组件没有name属性,导致如果使用exclude,改动的比较大,所以使用max属性,最多可以缓存多少组件的实例。max属性值必须大于0才能有效。
<keep-alive max="2">
<router-view></router-view>
</keep-alive>
二、案例练习
需求:切换路由组件时,Cats组件一直保持挂载状态,Dogs组件会被挂载与销毁
router/index.js代码
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
import Cats from "../pages/Cats";
import Dogs from "../pages/Dogs"
export default new VueRouter({
routes:[
{
path:'/cats',
component:Cats,
},
{
path:'/dogs',
component:Dogs,
},
]
})
App.vue代码
<template>
<div id="app">
<h3>动物学院</h3>
<router-link to="/cats">喵喵学院</router-link> 
<router-link to="/dogs">汪汪学院</router-link>
<!-- Cats路由组件保持挂载 -->
<keep-alive include = "Cats">
<router-view></router-view>
</keep-alive>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
Cats.vue代码
<template>
<div>
<p>我是喵喵学院成员</p>
<input type="text" placeholder="请输入文字">
</div>
</template>
<script>
export default {
name:"Cats",
}
</script>
Dogs.vue代码
<template>
<div>
<p>我是狗狗学院成员</p>
<input type="text" placeholder="请输入文字">
</div>
</template>
<script>
export default {
name:"Dogs",
}
</script>
运行结果
三、路由组件中独有的2个生命周期钩子
1、作用
路由组件所特有的2个生命周期函数,用于捕获路由组件的激活状态
2、具体钩子
当组件在<keep-alive>
内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
① activated
被 keep-alive 缓存的路由组件激活时调用
,该钩子在服务器端渲染期间不被调用
② deacivated
被 keep-alive 缓存的组件失活时调用
,该钩子在服务器端渲染期间不被调用。
3、用法
activated
和deacivated
2个生命周期钩子都必须配合<keep-alive>
标签使用
四、2个生命周期钩子案例
需求:在以上案例的基础上,在Cats组件中加入动画和定时器,当从Cats组件切走时,定时器结束
Cats.vue组件代码如下,其余组件不变
<template>
<div>
<p>我是喵喵学院成员</p>
<p :style="{opacity}">喵喵在线闪动</p>
<input type="text" placeholder="请输入文字">
</div>
</template>
<script>
export default {
name:"Cats",
data() {
return {
opacity:0
}
},
beforeDestroy(){
clearInterval(this.timer)
},
mounted() {
this.timer = setInterval(() => {
console.log("定时器一直在运行");
this.opacity += 0.01;
if(this.opacity >= 1) {
this.opacity = 0
}
}, 16);
},
activated(){
}
}
</script>
运行结果
(我们可以看到,使用<keep-alive>
缓存组件时,定时器一直会运行,造成内存消耗)
改进代码
将 mounted 和 beforeDestroy 两个钩子换成 activated 和 deactivated 钩子
activated() {
this.timer = setInterval(() => {
console.log("定时器一直在运行");
this.opacity += 0.01;
if(this.opacity >= 1) {
this.opacity = 0
}
}, 16);
},
deactivated(){
clearInterval(this.timer)
}
运行结果
五、总结
1、< keep-alive >
可以让不展示的路由组件保持挂载,不被销毁
2、当组件在< keep-alive >内切换,它的 activated 和 deactived 这两个生命周期钩子函数将会被对应执行。
3、如果同时使用include,exclude,那么exclude优先于include
, 下面的例子Cats组件不会被挂载
<keep-alive include="Cats" exclude="Cats">
<router-view></router-view>
</keep-alive>