应用场景:从列表页跳转到详情页面,然后从详情页返回列表页的时候,列表页的数据不刷新,但是从首页进行跳转到列表页的时候,列表页的数据刷新。

简单来说,是一个前进刷新,后退不刷新的功能。

使用localstorage+beforeRouteLeave实现

keep-alive是一个缓存的机制,keep-alive要配合router-view使用。使用keep-alive来缓存组件,防止二次渲染,这样会大大的节省性能。

使用方法:

<keep-alive>
    <router-view v-if="$route.meta.keepAlive">
        <!-- 这里是会被缓存的视图组件,比如 page1,page2 -->
    </router-view>
</keep-alive>

<router-view v-if="!$route.meta.keepAlive">
    <!-- 这里是不被缓存的视图组件,比如 page3 -->
</router-view>

在router/index.js中添加路由元信息,设置需要缓存的页面

    {
          path: '/page1',
          name: 'page1',
          component: page1,
          meta: {
              keepAlive: true, //此组件需要被缓存
              isBack:false, //用于判断上一个页面是哪个
          }
      },
      {
          path: '/page2',
          name: 'page2',
          component: page2,
          meta: {
              keepAlive: true, // 此组件需要被缓存
              isBack:false, //用于判断上一个页面是哪个
          }
      },

参考链接

1.第一次无法缓存问题:

但是这样的话会有一个问题,就是每次进入列表页面需要刷新一次才能开始缓存,第一次是不能进行缓存的,解决方案如下:

将router-view部分换成include模式,include里面的名字需要和组件页面的name对应上。
在这里插入图片描述

      <keep-alive :include="['Matter','Project','Contract','Arrive','Subcontract']">
        <router-view></router-view>
      </keep-alive>
      <!-- <router-view></router-view> -->

将需要缓存的页面放到include里面去,这样就可以解决这个问题了。但是这样只要打开页面都会开启缓存,包括任何页面返回列表页都不会刷新,所以还是需要配合activated 、 beforeRouteEnter 、 isBack:false使用。

另一个解决方案

beforeRouteEnter:

判断是从哪个路由过来的,如果不是overview过来的,表明当前页面不需要刷新获取新数据,直接用之前缓存的数据即可

// 列表页面跳转到 详情页时,设置需要缓存
  beforeRouteLeave(to, from, next) {
    if (to.path != "/overview") {
    //当离开的时候不是去首页的时候开启缓存
      from.meta.isBack = true;
    }
    next();
  },

因为这个页面需要缓存。只有第一次进入时才会执行created和mounted方法,再次进入就不执行了。而activated每次进入都执行,所以在这个钩子函数中获取数据。

// 列表页面
  activated() {
    
    if (!this.$route.meta.isBack) {
      //isBack 时添加中router中的元信息,判读是否要缓存
      this.resetQuery(); //清空原有数据
      this.getList(); // 重新加载
    }
    this.$route.meta.isBack = false; // 通过这个控制刷新,否则会一直为true
  },

第一次进入: beforeRouteEnter => created => … => activated => … => deactivated
后续进入:beforeRouteEnter => activated => deactivated,

以上的功能即为从首页进入列表页的时候刷新,从列表页去其他页面的时候不刷新,缓存。

2.同一个参数缓存不刷新问题:

但是以上的功能有一个问题是,如果被缓存的页面为:
在这里插入图片描述
在这里插入图片描述
这种同一个组件,但是带不同的参数时,点击不同的按钮,会进入同一个页面,不刷新。也就是vue中,路由相同,参数不同的页面如何使用 keep-alive 进行缓存问题。

修改为以下方式即可:

<keep-alive>
    <router-view :key="$route.fullPath"></router-view>
</keep-alive>

参考链接
另一个解决思路

3.保存后返回列表页刷新问题

如果修改了详情页,那么列表页的数据也需要刷新,由于这里的需求是表单的搜索条件保留,只刷新表格里面的内容,所以我这里采用的方法是:将this.getList();放到activated里面进行重新加载,这样的话每次返回的时候都会重新加载数据,而搜索条件只有从首页进入的时候才会刷新了。

// 列表页面
  activated() {
    
    if (!this.$route.meta.isBack) {
      //isBack 时添加中router中的元信息,判读是否要缓存
      this.resetQuery(); //清空原有数据
    
    }
      this.getList(); // 重新加载
    this.$route.meta.isBack = false; // 通过这个控制刷新,否则会一直为true
  },

每个项目的需求不同,在不同的项目中也可以将beforeRouteLeave放入到详细页面,或者储存一个值从详细页面带回来,判断是否需要刷新页面数据等方式。这样也可以避免一些错误,两个列表缓存页跳转时按钮点击无效等问题。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐