keep-alive基本用法
include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。
主要用于保留组件状态或避免重新渲染。
<!-- 基本 -->
<keep-alive><component :is="view"></component>
</keep-alive><!-- 多个条件判断的子组件 -->
<keep-alive><comp-a v-if="a > 1"></comp-a><comp-b v-else></comp-b>
</keep-alive><!-- 和 `<transition>` 一起使用 -->
<transition><keep-alive><component :is="view"></component></keep-alive>
</transition>
include 和 exclude prop 允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b"><component :is="view"></component>
</keep-alive><!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/"><component :is="view"></component>
</keep-alive><!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']"><component :is="view"></component>
</keep-alive>
匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。
被缓存的 组件会多出两个生命周期钩子函数
//此生命周期可以代替默认未缓存状态下mounted实例被挂载之后的生命周期
//即此生命周期只有在keep-alive缓存状态下才可生效activated(){console.log("组件被激活")this.count++this.getData("https://jsonplaceholder.typicode.com/todos/"+this.count)this.timeInterval()},//此生命周期可以代替destory钩子,对某些实例进行销毁deactivated(){console.log("组件被冻结")clearInterval(this.timer)}
keep-alive案例
问题:
如果想要router-view 里面某个组件被缓存除了include还可以在router-link换一种写法:
//routes配置
export default[{path:'/',name:'home',component:Home,meta:{keepAlive:true;//需要被缓存}},{path:'/:id',name:'home',component:Edit,meta:{keepAlive:false; //不需要被缓存}}
]
组件中的配置:
<keep-alive><router-view v-if='$route.meta.keepAlive'><!-- 这里是会被缓存的视图组件,比如 Home! --></router-view>
</keep-alive><router-view v-if='!$route.meta.keepAlive'><!-- 这里是不被缓存的视图组件,比如 Edit! --></router-view>
优点:不需要例举出需要被缓存组件名称
【附加】使用router.meta拓展
假设这里有3个路由:A、B、C。
需求:
默认显示A组件
B组件调到A组件,A组件不刷新
C组件跳到A组件,A组件刷新
实现方式
在A路由里面设置meta属性:
{path:'/',name:'A',component:Ameta:{keepAlive:true //需要被缓存}
}
在B组件路由里面设置beforeRouteLeave:
export default{data(){return{};methods:{};beforeRouteLeave(to,from,next){//设置从当前组件调到下一个组件设置下一个组件的路由meta的值变为trueto.meta.keepAlive=true;//让A缓存,既不刷新next();}}
}
在C组件里面设置beforeRouteLeave:
export default{
data(){
return{};
},
methods:{};
beforeRouteLeave(to,from,next){
//设置下一个路由的meta
to.meta.keepAlive=false;//让A不缓存,即刷新
}
}
这样既能实现B回到A,A不刷新,c到A,A刷新的操作
总结
路由大法不错,不需要关心哪个页面跳转过来的,只要 router.go(-1) 就能回去,不需要额外参数。
然而在非单页应用的时候,keep-alive 并不能有效的缓存了