需求是这样的:列表页进入详情页,列表页需要缓存,但从列表页进入首页(或其他页面),列表页不缓存。
网上解决方案有很多,可惜我智商不够,没成功,后来摸索出了一个解决方法。
首先,看一下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
插件,以后有空可以试一下。