写点什么

keep-alive+ 导航守卫让缓存更精确

作者:空城机
  • 2022 年 5 月 10 日
  • 本文字数:1730 字

    阅读完需:约 6 分钟

keep-alive+导航守卫让缓存更精确

之前已经写过Vue用keep-alive缓存组件介绍说明文章,但是还没有实际深入过,然后可以运用的例子就来了。

自己用node爬虫爬取小说章节,并提供了几个简单的node数据查询接口。然后制作了一个 vue 的简易小说阅读器项目(难度并不高,所以界面样式制作时间是最久😖)


组件需缓存分析

在小说阅读器中,只有三个界面:书架书籍目录, 章节阅读


这三个界面之间的关系:


实际场景效果:


这三个界面分别是三个 vue 组件,按照功能的区分,需要使用到keep-alive进行缓存的界面有两个,分别是书架书籍目录,其中的章节阅读基本每次都要重新刷新


虽然也会有重复点开同一章节的情况,但是先不做考虑,在专门卡bug么


然后对这两个页面需要做的keep-alive缓存功能也是不同的。


  • 书架界面:这是主界面,并且基本在第一次加载时所有需要的数据都已经存在,并不存在从书籍目录切换回来后数据就会改变的情况(虽然以后可能会有未读章节数据改变),所以直接整个缓存即可。


  • 书籍目录界面:因为此界面需要获取目录数据可能会较大,如果每次都重新创建,性能消耗过大。如果是点击某一章节看书,看完返回后又重新刷新,不太合适。所以在章节阅读界面回来后,可以直接keep-alive加载缓存。但是此时,如果keep-alive不做处理单纯缓存书籍目录也会有问题。因为书架选择不同书,书籍目录就需要改变。所以此界面需要根据来源页面不同进行缓存加载。


最终处理方案

  1. 先需要keep-alive缓存的组件和不缓存的区分,可以在路由的index.js文件中组件添加一个keepAlive属性判断此组件是否需要缓存。


题外话:vue cli 中直接用vue add router添加路由即可



添加好属性后,可以在主界面中这样写,需要缓存的就会自动被keep-alive包裹

<keep-alive>    <router-view v-if="$route.meta.keepAlive"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive"></router-view>
复制代码


当前的效果:(可以看到书架和书籍目录界面已经缓存了一次,并且之后的切换也不会重新刷新。而阅读章节并不受影响)


  1. 当前已经做好缓存区分了,并且对于书架来说,缓存的没有问题,那么就要对书籍目录组件单独处理了。 在vue-router中,有一个 beforeRouteEnter。 这是导航守卫中的组件内守卫,参考链接:vue-router导航卫士


该导航守卫是在渲染组件的对应路由被验证钱调用,可以使用三个参数:

所以可以在书籍目录组件中添加beforeRouteEnter

beforeRouteEnter: (to, from, next) => {    // // 判断路由来源界面    if (from.name == 'Home' | !from.name) {        next(vm=>{            // 从书架过来刷新数据            vm.getAllchapterFromApi();        });    } else {        next();    }}
复制代码


这样就完成了对应的跳转缓存。效果:


  1. 当然,此时会看到如果在书架中连续点击两次相同书籍,就会重复刷新,那么这类重复有没有办法解决?在我的页面跳转时,会有一个书本名称的参数传递,可以根据此来进行判断



错误经历

其实在导航卫士和keep-alive配合使用过程中,我想试试更多的方式,结果发现都需要书籍目录组件导航卫士的配合

错误思路 1

书籍目录组件中可以设置beforeRouteEnter,那么换位思考,能不能在上一个 from 的组件中使用beforeRouteLeave,然后发现在上一个组件中只能通过修改to.meta.keepAlive来做保证下一个组件不被缓存。

就这样写了:

 beforeRouteLeave(to, from, next) {    if (from.name == 'Home') {        to.meta.keepAlive = false    }    next()}
复制代码


看上去从书架到目录已经成功了,目录没有缓存。

但是...从章节阅读界面返回到目录时又重新刷新了


这样,可能会想当然的以为在阅读组件中也设置一个反向的to.meta.keepAlive = true是否可以,但结果是,书籍目录组件只会缓存第一本,书籍切换后,再返回,加载缓存时的也是第一本。


造成这个结果的原因是,缓存的组件其实本质上并没有进行更新,缓存的还是当初第一本的样子。


错误思路 2

在路由 index.js 文件中使用beforeEnter进行配置,但是还是和第一种一样,缓存仍未更新


总结


写代码的过程中,其实可以尽可能的将自己学习过的知识点应用出来。虽然有可能一个问题看起来好像有多种写法,但一种种试过去后,就发现自己想当然了。

虽然转牛角尖确实浪费时间,但是要把教训给记录下来,虽然以后自己会忘记,但是文字不会忘。


发布于: 2022 年 05 月 10 日阅读数: 43
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
keep-alive+导航守卫让缓存更精确_Vue_空城机_InfoQ写作社区