一、keep-Alive搭配vue-router实现缓存页面效果
1.1 keep-alive
<keep-alive>
是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。<keep-alive>
与<transition>
相似,只是一个抽象组件,它不会在DOM树中渲染(真实或者虚拟都不会),也不在父组件链中存在,比如:你永远在this.$parent
中找不到keep-alive
。
1.2 使用
给router-view添加keep-alive
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
router.js中添加meta
export default new Router({
routes: [
{
path: '/a',
name: 'A',
component: A,
meta: {
keepAlive: false // 不需要缓存
}
},
{
path: '/b',
name: 'B',
component: B,
meta: {
keepAlive: true // 需要被缓存
}
}
]
})
1.3 缓存组件的生命周期函数
缓存组件第一次
打开的时候,和普通组件一样,也需要执行created
, mounted
等函数。但是在被再次激活
和被停用
时,这几个普通组件的生命周期函数都不会执行,会执行两个比较独特的生命周期函数。
-
activated
这个会在缓存的组件重新激活时调用 -
deactivated
这个会在缓存的组件停用时调用
如不需要缓存的组件(商品详情页vue单文件组件),http://localhost:8081/productDetails/1,如果缓存商品详情页的话,商品id一直都是第一次路由传递过来的,导致不论点击哪个商品,商品详情都一样。但是想要获取最新传过来的路由参数的话可以在activated中获取,在组件的其它生命周期中获取的路由参数都是第一次传递过来的
activated () {
this.gameId = this.$route.params.gameId
}
组件停用时获取并存储当前scrollTop
经过测试,在 deactivated 方法里并不能准确的获取 scrollTop 值,每次都是 0
这里因为抽离了组件并且无法在 deactivated 中获取到scrollTop值,所以打算在点击商品跳转至商品详情页的点击事件中获取scrollTop值
goProductDetails (id) {
this.$emit('getScrollTop', this.$parent.$refs.mescroll.scrollTop)
}
<hot-product @getScrollTop="getScrollTop" />
// 获取点击商品跳转至商品详情页时记录当前的位置
getScrollTop (val) {
this.scroll = val
}
组件激活时取出并设置scrollTop
// 组件被激活时调用
activated () {
this.$refs.mescroll.scrollTop = this.scroll
}
二、keep-Alive比较新而且简单的用法
直接缓存所有组件/路由
<keep-alive>`` ``<router-view/>``</keep-alive>` `<keep-alive>`` ``<component :is=``"view"``></component>``</keep-alive>
使用include
来处理需要缓存的组件/路由
include
有几种用法,可以是数组,字符串用标点隔开,也可以是正则,使用正则的时候需要使用v-bind
来绑定。
<keep-alive include="['a','b']"> // 缓存name为a,b的组件
<keep-alive include ="a,b"> // 缓存name为a,b的组件
<keep-alive :include="/^store/"> // 缓存name以store开头的组件
<router-view/>//可以为router-view
<component :is="view"></component> // 也可以是动态组件
</keep-alive>
使用exclude
来排除不需要缓存的路由
跟
include
正好相反,在exclude
里的组件不会被缓存。用法类似,不作赘述
三、配合组件内的守卫,页面何时需要做缓存
当我们从home页到product页的时候,不需要缓存,从product页到productDetails页的时候需要缓存。这时候就要用到路由的钩子结合老版本用法来实现了。
product.vue组件中
beforeRouteEnter (to, from, next) {
// to将要访问的路径
// from代表从哪个路径跳转而来
if (from.name === 'home') {
to.meta.keepAlive = false
}
next()
},
beforeRouteLeave (to, from, next) {
if (to.name === 'productDetails') {
from.meta.keepAlive = true
}
next()
}