胖蔡说技术
随便扯扯

Vue项目中,路由都被缓存了,特定页面需要自定义刷新规则,怎么办?

最近开发的几个后台管理系统,都是基于vue-element-admin框架开发的。框架中,默认将所有页面进行了keep-alive缓存。但是在实际需求中,某些页面每次打开都需要刷新数据。这就出现了一个问题:

对于已被缓存的页面,如何进行数据刷新?

目前,在项目开发中,主要用到以下三种方式:

一、监听路由,刷新数据

js
watch: {
   $route: function (newVal) {
     if (/data-count\/firmCount/.test(newVal.path)) {
       this.init()
     }
   },
 },

init()方法中,将页面所有缓存的内容、操作的痕迹都进行了重置,让页面回到初始状态。也就是,每次打开目标页面,都如强制刷新一样,没有任何缓存的痕迹。

二、利用生命周期函数,刷新数据

通过keep-alive缓存后的页面,大部分的生命周期函数是不走的。比如:created,mounted等。能够走的生命周期函数就是:activated与deactivated。所以可以在activated生命周期函数中,进行数据刷新。

js
activated() {
    this.init()
},

init()方法的写法同上。

三、利用导航守卫清除缓存,刷新数据

js
beforeRouteLeave(to, from, next) {   //参数(马上去的页面,现在的页面,跳转)

    if(判断条件){
         to.meta.keepAlive = false  //将要去的那个页面的缓存清空

    }else{
       to.meta.keepAlive = true   //将要去的那个页面的缓存保留
    }
    next();
  },

相对来说,前两种方法比较简单粗暴,哪个页面需要就哪个页面使用,缺点就是每个页面需要重置的内容各不相同,处理比较繁琐。

而第三种方法,我们可以封装成一个公共的方法,在需要的页面引用即可。具体可以参考公司大佬的封装,如下:

js
//RouteMixin.js

export default {

  beforeRouteLeave(to, from, next) { // 离开路由之前执行的函数
    if (this.hasCached(from) && this.hasCached(to)) {
      const vnode = this.$vnode
      const key = vnode.key// 当前关闭的组件名
      if (key && vnode.parent) {
        const cache = vnode.parent.componentInstance.cache// 缓存的组件
        const keys = this.$vnode.parent.componentInstance.keys// 缓存的组件名
        if (keys) {
          keys.splice(0, keys.length)
        }
        if (cache) {
          for (const k in cache) {
            delete cache[k]
          }
        }
      }
    }
    if (this.hasCached(to)) {
      to.meta.keepAlive = true
    } else {
      to.meta.keepAlive = false
    }
    next()
  },
  methods: {
    hasCached(route) { // 根据需要定制缓存与否的规则
      const matched = route.matched
      const current = matched[matched.length - 1]
      const parent = current.parent
      if (parent && (parent.components.default.name === 'Layout' || parent.components.default.name === 'BlankLayout')) { 
        return true
      }
      return false
    },
  },

}

需求是千变万化的,这不,在vue-element-admin项目中,关于页面的缓存刷新,最近又遇到一个新问题:

对于已被缓存的页面,如何进行前进刷新后退不刷新?

也就是说,同一个页面,从上级页面或兄弟页面到达时,刷新,从下级页面返回时,不刷新。这应该怎么处理呢?
最终,进行一番搜索,解决如下:

在beforeRouteLeave中做标记,在activated中根据标记进行刷新与否的处理

js
beforeRouteLeave(to, from, next) {
   if (to.path === '/data-count/focusGroup') {//去下级页面时打标记
     this.$route.meta.isBack = true
   } else {
     this.$route.meta.isBack = false
   }
   next()
 },
 activated() {
   if (!this.$route.meta.isBack) {
     this.init()
   } 
 },

由此,又延申出一个问题:

从下级页面返回时,页面如何定位到历史位置?

处理过前进刷新后退不刷新的问题后,这个问题变得相对简单了,我们只需在上述代码的基础上,进行如下处理:

在beforeRouteLeave中记录scrollTop,在activated中根据记录的scrollTop进行位置处理

js
beforeRouteLeave(to, from, next) {
   if (to.path === '/data-count/focusGroup') {
     this.$route.meta.isBack = true
     this.scrollTop = this.$refs.proTable.$el.scrollTop || 0 // 新增的代码
   } else {
     this.$route.meta.isBack = false
   }
   next()
 },
 activated() {
   if (!this.$route.meta.isBack) {
     this.init()
   } else {
     this.$refs.proTable.$el.scrollTop = this.scrollTop // 新增的代码
   }
 },
赞(1) 打赏
转载请附上原文出处链接:胖蔡说技术 » Vue项目中,路由都被缓存了,特定页面需要自定义刷新规则,怎么办?
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏