怎么介绍呢,只能说是我今年面试的时候每一家公司都问了,好了正片开始。
什么是keep-alive
<keep-alive>
是一个内置组件,允许我们在多个组件之间动态切换时,有条件地缓存组件实例。使被包含的组件保留状态,或避免重新渲染
为什么使用
在开发过程中,有部分组件没有必要多次初始化,这时,我们就需要将组件进行持久化,使组件的状态维持不变,在下一次展示时,组件也不会进行重新初始化。
用法
含有属性:
- include: String| RegExp | Array。只有匹配的组件会被缓存。(使用字符串形式时用‘ , ’隔开且组件名之间不要留有空格)
- exclude: String| RegExp | Array。任何匹配的组件都不会被缓存。(使用字符串形式时用‘ , ’隔开且组件名之间不要留有空格)
- max:Number | String。缓存的组件实例的最大数量,如果缓存实例的数量即将超过指定的最大计数,则最近访问最少的缓存实例将被销毁,以便为新实例腾出空间。
基本用法:
<!--被keepalive包含的组件会被缓存-->
<keep-alive>
<component><component />
</keep-alive>
有其他属性时:
<!-- 只缓存组件name为a或者b的组件, 结合动态组件使用,currentTab是我data中定义的动态组件名,下面情况相同,就不做相同解释了 -->
<keep-alive exclude="a,b">
<component :is="currentTab"></component>
</keep-alive>
<!-- 组件名为c的组件不缓存,即不重新渲染-->
<keep-alive exclude="c">
<component :is="currentTab"></component>
</keep-alive>
<!-- 使用正则表达式,需使用v-bind -->
<keep-alive :include="/a|b/">
<component :is="currentTab"></component>
</keep-alive>
<!-- 如果同时使用include,exclude,那么exclude优先于include, 下面的例子只缓存a,c组件 -->
<keep-alive include="a,b,c" exclude="b">
<component :is="currentTab"></component>
</keep-alive>
<!-- 如果缓存的组件超过了max设定的值5,那么将删除第一个缓存的组件 -->
<keep-alive exclude="a" max="5">
<component :is="currentTab"></component>
</keep-alive>
注:
生命周期
当我们缓存某组件实例时,它会进入停用状态而不是被卸载。当组件实例作为缓存树的一部分插入 DOM 时,它会被激活。
keep-alive
中创建的组件,会多出两个生命周期的钩子: activated
与 deactivated
:
- activated 当 keepalive 包含的组件被激活(使用)的时候触发,可以简单理解为进入这个页面的时候触发
- deactivated 当 keepalive 包含的组件不被使用(inactive状态)的时候触发,可以简单理解为离开这个页面的时候触发
假设我们缓存About组件,在About组件中编写以下代码并执行:
created() {
console.log("我是created钩子");
},
mounted() {
console.log("我是mounted钩子");
},
activated() {
console.log("我是activated钩子");
},
deactivated() {
console.log("我是deactivated钩子");
},
beforeDestroy() {
console.log("我是beforeDestroy钩子");
},
首次进入页面,钩子的触发顺序:
我是created钩子 —〉 我是mounted钩子 —〉 我是activated钩子
离开页面:
我是deactivated钩子
——————————————————————————————
再次进入:
我是activated钩子
离开:
我是deactivated钩子
vue-router 结合router使用
基本使用:
//缓存所有
<keep-alive>
<router-view>
</router-view>
</keep-alive>
如果我们要缓存部分:
- 使用
include
/exclude
- 使用
meta
属性
第一种方式的使用方式:
//只有路径匹配到的 include 为 home 组件会被缓存
<keep-alive include="home">
<router-view>
</router-view>
</keep-alive>
exclude用法类似,我就不演示了,大家可以自己试一下
第二种方式:
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
router中进行相应配置:
export default new Router({
routes: [
{
path: '/home',
name: 'Home',
component: Home,
meta: {
keepAlive: false // 不需要缓存
}
},
{
path: '/About',
name: 'About',
component: About,
meta: {
keepAlive: true // 需要被缓存
}
}
]
})
另外说个之前朋友在群里问的一个问题,原纪录找不到了,大体意思就是Home,About,List三个组件,Home跳List List不刷新,About跳List List刷新
说下如何实现哈:
可以像上面一样,给List设置下meta
然后在 Home 组件里面设置 beforeRouteLeave:
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta。可以先判断下是否是List,我这就不判断了,直接写keepAlive配置了
to.meta.keepAlive = true; // 让 List 缓存,即不刷新
next();
}
然后在 About 组件里面设置 beforeRouteLeave:
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta。同样可以先判断一下我就不写了
to.meta.keepAlive = false; // 让 List 不缓存
next();
}
完结撒花🎉,如有不对欢迎指正。觉得有帮助的话记得点个赞哦~