1 简介
起因是之前曾经碰到的需求,需要实现类似传统后台管理页面的标签页功能。
需求如下:
- 点击左侧菜单栏,在主页面上层会新增标签页
- 标签页可以点击切换页面,也可以点击关闭
- 当标签页存在的时候,切换的页面需要缓存页面上的数据。当标签页关闭的时候,需要清除缓存的数据。
2 初步解决
当时第一时间想到的就是vue
自带的keep-alive
组件,再把标签的数据存放在vuex
当中,通过新增以及删除数据来控制keep-alive
的include
属性,达到数据缓存的功能。
3 遇到的问题
对于keep-alive
的原理来说,它是通过组件的name
属性值来进行判断并缓存组件的instance
实例等到下次再来用。
普通的页面其实没有问题,可以正常使用。但是平时我们开发中有一类复用的页面,比如一个列表页面,里面的每个列表都是链接到一个详情页,正常我们就是携带一个id的参数到路由,然后打开详情页。这个详情页其实是复用的,但是这些页面的name
都是相同的,这种情况下,keep-alive
就只会缓存最新的那个组件实例,功能就有问题了。
4 尝试解决
页面的状态可不可以使用js来保存?
我抱着这种想法去尝试做了一套流程,核心实现是页面中的路由事件来让复用页面把数据存到自己的变量当中,通过传入的id来判断是否需要重新获取。然后在标签页关闭的时候,调用一个方法来判断清除复用页面的数据。
虽然功能实现了,但是复用页面还没写业务的逻辑代码,就已经显的十分臃肿,标签页关闭的时候还需要添加一个非常耦合的清除事件。十分的不友好,后面还是放弃了这种方式,复用页面就不去缓存了。
5 新的思路
下面这个是我新实现的缓存页面功能,使用了一个我基于keep-alive
实现的一个vue组件all-keep-alive。它完美的解决上面的复用页面的缓存问题,而且复用页面不需要添加任何的功能。
这是之前在学习keep-alive的源码的时候产生的灵感,一直没时间写,这段时间终于抽空完成了。
keep-alive
实现缓存的原理,是通过组件的name
来匹配,然后通过组件vnode
的实例cid和tag生成一个key,通过key获取缓存。这里的缓存不是js数据,而是组件vnode
的实例componentInstance
。keep-alive
相当于直接使用这个实例进行页面的render
,实现了缓存的功能。
我就基于这个核心功能,把name
修改为了组件的路由参数,因为路由参数肯定是固定的,通过这个来判断,可以实现对所有页面的无差别缓存。
具体使用就看我的github吧
注意: 这是vue2的版本!!
vue3正式版上周出来了,后续我再加个vue3的版本吧
欢迎大家star,提供issues。
5、感谢
首先感谢您的浏览,希望您能够动动小手给咱点个赞,谢谢大家。
本文使用 mdnice 排版