Vue缓存 菜单、多Tab解决方案

1.需求

在项目开发中,前端不免遇到须要路由缓存的需求。在以前一个React项目中,查询各类资料和插件后,了解到React要配合React-router进行路由缓存,会有不少意想不到的问题。因此在React项目中,咱们都避免接收到须要路由缓存的需求。前端

最近在开发一个vue项目中,因为vue原生有Keep-alive组件以及includeexclude的各类api来实现路由缓存。因此咱们决定大胆的接下这个坑。vue

2.踩坑

一开始咱们也是直接用keep-alive包裹住router-view  加上路由的fullPath做为router-viewkey值,而后用include定义须要缓存的组件。node


以及在路由定制的meta里面定义keepalive是否须要缓存字段来处理缓存vuex


对于通常的项目,其实这样解决缓存已经能够了。可是咱们是对应B端的管理系统,会有菜单页,Tab页,一个路由可能在不一样的状况会须要缓存以及不须要缓存两种状况。在动态改变keepaliveList或者$route.meta.keepalive后,并无触发组件缓存的销毁以及再缓存。因此咱们只能变换方法来实现。element-ui

3.解决思路--清理详情页缓存

咱们的项目会有多个Tab的形式,相似于element-ui的tabs组件。api

咱们在相同tab下的路由配置了相同的pageKey表明在一个tab下的路由组件。缓存

按照上面的配置,组件A,B是在一个tab下,C是在另外一个tab下的。app

在用keep-alive包裹住router-view后,能够实现切换不一样tab,切换路由,缓存页面,可是在同一个tab下从列表跳到详情页,咱们须要详情页每次进入都须要清楚缓存从新查询数据。介于有这两种须要不一样缓存效果的组件,咱们在路由定义时多加了一个noCache字段,定义了这个字段的路由,代表在不一样pageKey路由(表示不一样tab)之间切换时,须要缓存,在相同pageKey(表示同一tab)路由之间切换时,不须要缓存并清理。函数

在查询资料后,了解到vue把缓存组件存储到$vnode.parent.componentInstance.cache中,咱们想到了一个用vue路由钩子清理缓存的一个方法。ui


以上代码是在第一次打开详情页返回到列表页时,进入beforeRouteLeave钩子函数,调用clearCache方法清除详情页的缓存。

4.解决思路--关闭tab清理缓存

如今还有一个问题是每一个tab会有关闭按钮,在点击一个tab的关闭按钮后,应该清除该tab同一个pageKey的全部组件缓存。这里咱们在点击关闭按钮事件中设置vuex全局变量在全局beforeRouteLeave的判断里加上该判断,若是全局变量变化说明点击了关闭按钮,而后再clearCache方法内部清除相同pageKey的组件cache列表。

5.解决思路--返回列表缓存查询条件并重查数据

到这里其实大部分的缓存问题已经解决了,可是咱们可爱的产品爸爸,忽然给咱们提了一个新的需求,在详情页跳转到列表页的时候,须要列表页的查询条件存在,而且重查一次查询。刚开始咱们决定考虑新的解决思路来清理列表页的缓存,而且存储下列表页的查询条件。因为咱们列表页不会设置noCache字段,因此查询列表的条件缓存是存在的,咱们只须要从新调一次查询接口就能够了。

根据这个思路,咱们在详情页跳转回列表页时给详情页meta对象新增一个backSearch字段,在beforeRouteLeave中若是捕获到from.meta.backSearch,则删除这个属性而且设置to.meta.backSearch=true,再设置一个全局actived缓存钩子若是检测到该路由的meta.backSearch字段,则自动调用组件定义的myOption方法实则为该组件的查询方法

6.解决思路--url随机数清理缓存

以上大概解决了业务提的全部缓存需求。可是在最近的开发中,因为用户的骚操做,又爆发出了缓存的又一bug。

咱们清理详情页缓存的触发条件是,相同pageKey之间跳转的状况,例如详情页跳转回列表页,可是用户的一次操做是进入了详情页直接点击菜单进入了其余页面,而后点列表菜单从新进入列表页,路由全在不一样pageKey的状况下跳转,并无触发详情页缓存逻辑。

在注意到咱们的router-view key字段是$route.fullPath,因此咱们决定给url加上随机数来解决这个问题。

7.结语

目前我没找寻到一个业界比较公认的缓存解决办法,咱们也在探索之中。咱们的方法可能比较繁琐,但目前能解决咱们的开发需求,若是有大佬能给咱们提一些宝贵的意见,咱们会很是感谢。

相关文章
相关标签/搜索