需求是这样的:列表页进入详情页,列表页需要缓存,但从列表页进入首页(或其他页面),列表页不缓存。
网上解决方案有很多,可惜我智商不够,没成功,后来摸索出了一个解决方法。
首先,看一下keep-alive的源码:
// 只看下面一段
mounted () {
this.$watch('include', val => {
pruneCache(this, name => matches(val, name))
})
this.$watch('exclude', val => {
pruneCache(this, name => !matches(val, name))
})
},
keep-alive监听了include和exclude。这里我只用到了include,做法是列表页一直缓存,在从列表页进入首页的时候,设置列表页不缓存,再调用this.$nextTick将列表页设置为缓存,防止下一次进入列表页的时候,列表页不在include中而没有缓存。有点绕,简单来说就是在进入首页的时候清一下列表页的缓存(重置)。代码如下:
// router.js
{
path: '/latest',
name: 'Latest',
component: () => import('@/views/latest'),
meta: {
keep: true // 是否缓存组件
}
}
<template>
<div id="app">
<Header></Header>
<div class="content-container" :class="$route.meta.scroller ? 'no-padding' : ''">
<keep-alive :include="cacheViews" ref="keepAlive">
<router-view :key="$route.fullPath"></router-view>
</keep-alive>
</div>
</div>
</template>
<script>
import Header from '@/components/Header'
export default {
name: 'App',
components: {
Header
},
computed: {
// 需要缓存的页面数组放到了 vuex 中
cacheViews() {
return this.$store.state.app.cacheViews
}
},
watch: {
$route: {
handler(to, from) {
this.changeKeep(to, from)
}
}
},
methods: {
// 改变路由缓存字段
changeKeep(to, from) {
if (to.name === 'BookDetail') {
from.meta.keep = true
} else {
from.meta.keep = false
this.$nextTick(() => {
from.meta.keep = true
this.setCacheViews(to, from)
})
}
this.setCacheViews(to, from)
},
// 设置缓存页面
setCacheViews(to, from) {
let routes = this.$router.options.routes
routes = routes.filter(route => route.meta && route.meta.keep).map(route => route.name)
this.$store.commit('app/SET_DATA', {
cacheViews: routes
})
console.log(routes)
},
}
}
</script>
这样基本算是解决了keep-alive缓存的问题。
题外话:webApp的开发体验能不能更好一点呢?比如路由页面缓存、前进、后退等问题总是让人头疼。刚刚好像看到一个vue-page-stack插件,以后有空可以试一下。