Vue中刷新当前页的几种方式及优劣分析
这个问题其实百度一下就有一堆解决方案,但是却很少有文章去分析他们各自的优势和劣势,而我这篇文章,也是在具体项目开发中,踩过一些坑后的心得和总结。
方案一
基本不会使用的方案,就是通过 location.reload()
或者 $router.go(0)
进行一次页面重新载入,效果等同于手动按 F5 刷新。
为什么说基本不用,因为弊端也很明显。首先体验不好,页面重新载入会出现大段时间的白屏;其次如果使用了 Vuex ,刷新可能会导致数据被清空。
方案二
准备一个空白页,页面里只做一件事,就是 $router.go(-1)
,需要刷新当前页的时候,只需跳转到该页面即可。
这个方案也会出现一小段白屏的时间,但问题不大,可以通过一些 loading 效果遮盖;其次因为是前进到一个空白页,再返回当前页,在 PC 端会出现一个小的 bug ,就是刷新一次之后,浏览器上的前进按钮会变成可点击,演示如下图:
方案三
网上能搜到最推荐的解决方案。就是通过 v-if
控制 <router-view>
的显示,如果要刷新页面,则将 <router-view>
销毁再重建一次即可。具体实现代码如下:
主要改造的就是 App.vue 文件
1 | <template> |
通过 Vue 的 provide / inject ,将 App.vue 里的 reload()
方法注入到子页面里,这样在子页面里就可以通过这样的方式使用了。
1 | <script> |
当然还可以更极致一点,就是直接在 App.vue 里监听路由的变化,如果当前路由和上一个路由的 name 属性一样,则可以认为是刷新页面操作,自动执行 reload()
方法。实现代码如下:
1 | <template> |
这样的好处在于,如果是在同一个路由,但不同参数间的跳转,能实现自动刷新页面。例如商城系统里最常见的,从一个商品详情页跳转到另一个商品详情页,这个时候,路由其实是没变化的,变化的只是 params 或者 query ,就不需要手动再去执行注入的 reload()
方法了。
这个方案看起来很完美,但有没有弊端呢?其实是有的,就是当项目在使用 keep-alive 做页面缓存的时候,会出现明显的问题。
因为一般做页面缓存都是通过 keep-alive 将 <router-view>
进行整页缓存,而刷新页面则是将 <router-view>
销毁并重建,所以一刷新,缓存就一并销毁了,所以在一些比较特殊的场景,还是有问题存在。
在遇到这样需要缓存页面的场景,方案二就体现出它的优势了。因为它是通过路由跳转刷新当前页面的,所以 <router-view>
始终都存在,就也能保证 keep-alive 的页面缓存不受到任何影响。
方案四
这种属于不太通用处理办法,就是在当前页面里手动再次获取相关数据,覆盖原有数据,实现刷新。这个方案的好处就是自由度更高,想重新获取哪些数据,就获取哪些数据,当然开发效率也会变低,因为无法形成通用的方案,到底要刷新哪部分数据,每个页面的业务逻辑都不一样。
总结
说白了,其实没有一种方案是完美的,还是得根据不同的场景,选择适合的解决方案。当然我个人还是更喜欢方案二和方案三结合使用,因为页面缓存使用的场景也是挺多的。