vue中使用keepAlive组件缓存,如何清缓存(有些时候页面不需要缓存)

项目开发中在用户由分类页category进入detail需保存用户状态,查阅了Vue官网后,发现vue2.0提供了一个keep-alive组件。
上一篇讲了keep-alive的基本用法,现在说说遇到的坑。
先说项目中的配置
 
在App.vue中的设置

 

 在router中增加配置meta

 

 

上面这个设置后发现问题了,从category进入detail页后,状态被保存了,返回的时候保存了用户状态,达到了预期效果
但问题在于但从category返回到index后,再由index进入category时依然显示是缓存中的页面,此刻页面没有刷新。
返回index后的组件显示如下:
 

 

 

分析从index再次进入category时,直接读取了缓存的里的页面。
头大。。。。。。。我的目标只是缓存从category进入detail页面,其他的时候不缓存。
 
 
解决方案
在category中启用beforeRouteLeave钩子函数
beforeRouteLeave中只有从category进入detail时才进行缓存,其他页面都讲category的keepalive设置成false,并销毁此category组件;

 

 

然而,发现新的问题。。。。。。
第一次操作index--> category ---> detail的时候是理想效果,但当第二次操作返回index后,进行index --> category --> detail --> category时,发现缓存的对象又不对了,从detail返回category时,保存是的第一次进入detail的分类情况。
此刻category的组件显示如下

 

 

无奈。。。。。对比了第一次和第二次进入页面情况
 
根据vue-router提供的守卫可在路由中启用afterEach路由守卫,在afterEach中进行判断是否第一次进入,非第一次进入页面情况强制刷新一次category页面。 

 

以上是我查看的网上解决问题的灵感文章,下面是我再开发中遇到问题的解决过程: (遇到相同问题的小伙伴可以参考下

一、需求描述

       a. 列表页(A)、新增表单页(B)、选择车位号列表页(C)

       b . 首先从A跳到B,B是不需要缓存的

       c. 从B跳到C,B需要缓存保存之前填写的form表单的所有内容

  (我这边还有一个编辑页,需要公用B页面,只是把内容回显到B页面而已,后面再续写如何回显B,第一次的进入的时候回显,C再跳到B则不需要回显,只需缓存了)

二、解决思路

     a. B路由设置keep-alive: true, 另外增加一个isIndex: false, 用来判断是否需要清缓存,从列表页A跳进来就要清,C页面跳进来则不需要清

  b. 弄清楚mounted, actived, deactived 三个周期函数的执行过程

   组件设置了keep-alive缓存,第一次进来的时候会执行mounted, actived,第二次进入时只会执行actived,不会执行mounted函数了,离开的时候都会执行deactived 

  必须要清楚这块,不然清缓存会很痛苦的

三、解决过程及部分代码结果

  rounte.js 

{
      path: '/newMonthApply', // 月卡申请新增
      name: 'newMonthApply',
      component: () => import('../views/monthCarApplication/newMonthApply.vue'),
      meta: {
        title: '开通月卡申请',
        keepAlive: true,
        isIndex: false, // 用来清从列表页进入的缓存
        isEdit: false // 用来判断是不是当前页是不是编辑页,回显数据
      }
    },

 index.vue (A列表页)

beforeRouteLeave(to, from, next) {
      if (to.name == 'newMonthApply') {
        to.meta.isIndex = true // 设置inIndex = tre
      }
      next();
    },

  

newMonthApply.vue  (B页面)
beforeRouteEnter (to, from, next) {
      next(vm => {
        //因为当钩子执行前,组件实例还没被创建
        // vm 就是当前组件的实例相当于上面的 this,所以在 next 方法里你就可以把 vm 当 this 来用了。
        console.log(vm);//当前组件的实例
        if (from.name == 'monthCarApplyDetal' && to.name == "newMonthApply") {
          to.meta.title = "编辑月卡申请"
        }
        // 为div元素重新设置保存的scrollTop值
        document.querySelector('.recordContent').scrollTop = vm.scrollY 
      });
    },
//记录离开时的位置
beforeRouteLeave (to, from, next) { 
        //保存滚动条元素div的scrollTop值
        this.scrollY = document.querySelector('.recordContent').scrollTop
        console.log('离开时保存滚动条的位置', this.scrollY)    
      next()
    },
mounted() {
      this.textSize = 0
      if (this.$route.query.row != undefined) {
        console.log('===========编辑申请表单信息==============')
        this.rowData = JSON.parse(this.$route.query.row)
        // this.carsInfo = JSON.parse(this.$route.query.carsInfo)
        console.log('rowData', this.rowData)
        this.editDataHandle(this.rowData)
      } else {
        console.log('===========新增申请表单信息监听2==============')
        this.resetForm()
      }
      this.$nextTick(()=>{
        this.box = document.querySelector('.recordContent')
        this.box.addEventListener('scroll', function(){
          this.scrollY = document.querySelector('.recordContent').scrollTop
          console.log("scrollY", this.scrollY)
        }, false)
      })
    },
activated() {
      console.log('this.$route.meta.isIndex', this.$route.meta.isIndex)
      if (this.$route.meta.isEdit) { // 从编辑页进去的话需要需要从新填写表单信息
        if (this.$route.query.row != undefined) { 
          console.log('===========编辑申请表单信息==============')
          this.rowData = JSON.parse(this.$route.query.row)
          // this.carsInfo = JSON.parse(this.$route.query.carsInfo)
          console.log('rowData', this.rowData)
          this.editDataHandle(this.rowData)
        } else {
          console.log('===========新增申请表单信息监听2==============')
          this.resetForm()
        }
      }
      if (this.$route.meta.isIndex) { //从首页进入,不需要缓存
        this.resetForm()
        // console.log('rowData', this.rowData)
      }
    },

 

车位号搜索页.vue (C页面)

// 从车位页返回主页时把主页的keepAlive值设置为true(要做个判断,判断是不是返回到主页的)
    beforeRouteLeave (to, from, next) {
      if (to.name === 'newMonthCard' || to.name === 'monthCarModify' || to.name === 'newFreeCard' || to.name === 'freeCarModify' || to.name === 'newMonthApply' || to.name === 'newFreeApply') { // 需要缓存
        to.meta.isIndex = false
        to.meta.isEdit = false
      }
      next()
    },

 

 

 
posted @ 2020-05-18 10:40  front-gl  阅读(18154)  评论(0编辑  收藏  举报