keep-alive+ 导航守卫让缓存更精确
之前已经写过Vue用keep-alive缓存组件
介绍说明文章,但是还没有实际深入过,然后可以运用的例子就来了。
自己用node
爬虫爬取小说章节,并提供了几个简单的node
数据查询接口。然后制作了一个 vue 的简易小说阅读器项目(难度并不高,所以界面样式制作时间是最久😖)
组件需缓存分析
在小说阅读器中,只有三个界面:书架
,书籍目录
, 章节阅读
这三个界面之间的关系:
实际场景效果:
这三个界面分别是三个 vue 组件,按照功能的区分,需要使用到keep-alive
进行缓存的界面有两个,分别是书架
和书籍目录
,其中的章节阅读基本每次都要重新刷新
虽然也会有重复点开同一章节的情况,但是先不做考虑,在专门卡bug么
然后对这两个页面需要做的keep-alive
缓存功能也是不同的。
书架
界面:这是主界面,并且基本在第一次加载时所有需要的数据都已经存在,并不存在从书籍目录
切换回来后数据就会改变的情况(虽然以后可能会有未读章节数据改变
),所以直接整个缓存即可。
书籍目录
界面:因为此界面需要获取目录数据可能会较大,如果每次都重新创建,性能消耗过大。如果是点击某一章节看书,看完返回后又重新刷新,不太合适。所以在章节阅读
界面回来后,可以直接keep-alive
加载缓存。但是此时,如果keep-alive
不做处理单纯缓存书籍目录
也会有问题。因为书架
选择不同书,书籍目录
就需要改变。所以此界面需要根据来源页面不同进行缓存加载。
最终处理方案
先需要
keep-alive
缓存的组件和不缓存的区分,可以在路由的index.js
文件中组件添加一个keepAlive
属性判断此组件是否需要缓存。
题外话:vue cli 中直接用
vue add router
添加路由即可
添加好属性后,可以在主界面中这样写,需要缓存的就会自动被keep-alive
包裹
当前的效果:(可以看到书架和书籍目录界面已经缓存了一次,并且之后的切换也不会重新刷新。而阅读章节并不受影响)
当前已经做好缓存区分了,并且对于书架来说,缓存的没有问题,那么就要对书籍目录组件单独处理了。 在
vue-router
中,有一个 beforeRouteEnter。 这是导航守卫中的组件内守卫,参考链接:vue-router导航卫士
该导航守卫是在渲染组件的对应路由被验证钱调用,可以使用三个参数:
所以可以在书籍目录
组件中添加beforeRouteEnter
这样就完成了对应的跳转缓存。效果:
当然,此时会看到如果在
书架
中连续点击两次相同书籍,就会重复刷新,那么这类重复有没有办法解决?在我的页面跳转时,会有一个书本名称的参数传递,可以根据此来进行判断
错误经历
其实在导航卫士和keep-alive
配合使用过程中,我想试试更多的方式,结果发现都需要书籍目录
组件导航卫士的配合
错误思路 1
在书籍目录
组件中可以设置beforeRouteEnter
,那么换位思考,能不能在上一个 from 的组件中使用beforeRouteLeave
,然后发现在上一个组件中只能通过修改to.meta.keepAlive
来做保证下一个组件不被缓存。
就这样写了:
看上去从书架到目录已经成功了,目录没有缓存。
但是...从章节阅读界面返回到目录时又重新刷新了
这样,可能会想当然的以为在阅读组件中也设置一个反向的to.meta.keepAlive = true
是否可以,但结果是,书籍目录
组件只会缓存第一本,书籍切换后,再返回,加载缓存时的也是第一本。
造成这个结果的原因是,缓存的组件其实本质上并没有进行更新,缓存的还是当初第一本的样子。
错误思路 2
在路由 index.js 文件中使用beforeEnter
进行配置,但是还是和第一种一样,缓存仍未更新
总结
写代码的过程中,其实可以尽可能的将自己学习过的知识点应用出来。虽然有可能一个问题看起来好像有多种写法,但一种种试过去后,就发现自己想当然了。
虽然转牛角尖确实浪费时间,但是要把教训给记录下来,虽然以后自己会忘记,但是文字不会忘。
版权声明: 本文为 InfoQ 作者【空城机】的原创文章。
原文链接:【http://xie.infoq.cn/article/8b8396156c663e5e45fd62718】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论