zoukankan      html  css  js  c++  java
  • 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()
        },
     
  • 相关阅读:
    数据类型
    springboot中get post put delete 请求
    图解SQL的inner join、left join、right join、full outer join、union、union all的区别
    【转】MyBatis之级联——一对一关系
    【转】浏览器同源政策及其规避方法(2)
    【转】浏览器同源政策及其规避方法(1)
    Spring Boot配置文件详解
    【BUG】Spring Mvc使用Jackson进行json转对象时,遇到的字符串转日期的异常处理(JSON parse error: Can not deserialize value of type java.util.Date from String[])
    【转】SpringBoot Mybatis 读取配置文件
    MySQL
  • 原文地址:https://www.cnblogs.com/mmzuo-798/p/12909191.html
Copyright © 2011-2022 走看看