keep-alive 保持活跃,在vue中我们可以用其来保存组件的状态,对组件进行缓存。
keep-alive 我们常在列表页使用,比如我们在业务上经常会有要求,当查看完某一列表详情页时,返回列表页,需要回到原来的位置,并保持页面的状态。
回到页面的初始位置,我们可以在router.js中使用scrollBehavior来实现,如回到页面顶部
scrollBehavior (to, from, savedPosition) { return { x: 0, y: 0 } }
指定位置
scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition } else { return { x: 0, y: 0 } } }
言归正传,回到我们的keep-alive
一般情况下,组件进行切换的时候,默认会进行销毁,如果有需求,某个组件切换后不进行销毁,而是保存之前的状态,那么就可以利用keep-alive来实现
举例:两个组件
{ path: '/cofather', name: 'cofather', component: () => import('../views/Cofather.vue') }, { path: '/compontent', name: 'compontent', component: () => import('../views/Common.vue') }
为两个组件分别添加一个输入框,这时我们切换组件,输入框的值不会保存
因为在切换时组件会触发destroyed,销毁组件
此时我们就可以利用keep-alive组件进行包裹router-view组件,将不活动的组件缓存起来
<keep-alive> <router-view/> </keep-alive>
这时我们会发现切换组件时两个组件输入框的值都保存起来了
那么,我们如果只需要其中一个组件缓存,比如cofather组件缓存时,我们就需要keep-alive的两个属性了
- include 值为字符串或者正则表达式匹配的组件name会被缓存。
- exclude 值为字符串或正则表达式匹配的组件name不会被缓存。
注意:include 值是组件中的name命名,而不是路由中的组件name命名
<keep-alive include="cofather"> <router-view/> </keep-alive>
<template> <div> <p>父组件</p> <div style="width: 300px;margin:0 auto;"> <el-input v-model="inputval"></el-input> </div> </div> </template> <script> import api from "@/axios"; import httpConfig from "@/config/http"; export default { name: "cofather", data() { return { inputval: '' }; }, }; </script>
此时我们就会发现我们会发现cofather已经被缓存了,但是compontent没有被缓存
而exclude就是排除了,这个就不在演示了,很简单
除了这个我们还可以利用路由中的meta属性来控制
{ path: '/cofather', name: 'cofather', meta:{ keepAlive:true }, component: () => import('../views/Cofather.vue') },
将cofather的路由规则中的meta添加keepAlive属性为true,也就是当前路由组件要进行缓存
keep-alive代码可以结合v-if进行包裹,如果meta中的keepAlive为true进行缓存,否侧不进行缓存,这样可以更灵活一些
<keep-alive> <router-view v-if="$route.meta.keepAlive" /> </keep-alive> <router-view v-if="!$route.meta.keepAlive" />
这样组件的缓存是实现了,但是还是会有一些问题,就是因为组件被缓存,并没有被销毁,
所以组件在切换的时候也就不会被重新创建,自然也就不会调用created等生命周期函数,
所以此时要使用activated与deactivated来获取当前组件是否处于活动状态
我在cofather组件里面写入了activated与deactivated生命周期函数
activated() { console.log("----------进activated--------"); }, deactivated() { console.log("----------进deactivated--------"); }
同时,实践中我们可以结合路由守卫来实现需要缓存组件的缓存
beforeRouteLeave(to, from, next) { if (to.path === "/goods_detail") { from.meta.keepAlive = true; } else { from.meta.keepAlive = false; // this.$destroy() } next(); }