天天看点

Vue3.0使用keep-alive实现页面缓存不刷新

一.应用场景

1.列表页进入详情页,再从详情页返回列表页;列表页缓存不刷新。保持原来选中的查询参数以及当前页

2.某个新增页面分为两步,分为A页面和B页面;当第一步A页面信息填好后,点击下一步到第二步B页面。再返回到第一步A页面,A页面信息不丢失。同理第二步填好信息返回到第一步,再回到第二页,第二页页面信息不丢失。

二.解决步骤

1.App.vue

//isRouterAlive:通过先设置isRouterAlive为false再设置为true可实现组件的销毁
<router-view v-slot="{ Component }" v-if="isRouterAlive">
    <keep-alive>
          <component :is="Component" v-if="_this.$route.meta.keepAlive" :key="$route.name" />
    </keep-alive>
    <component :is="Component" v-if="!_this.$route.meta.keepAlive" />
</router-view>      

2.router.js

//设置meta
const routes: Array<RouteRecordRaw> = [
   {
        path: 'list',
        name: 'list',
        meta: { keepAlive: true, cacheList: ['detail'] },
        component: () => import('@/views/list.vue')
    },
]
//路由拦截
router.beforeEach((to, from, next) => {
   //从cacheList中的任何一个页面返回,当前页面缓存
   const cacheList: any = to.meta.cacheList
   if (cacheList) {
      if (cacheList.indexOf(from.name) > -1) {
          to.meta.keepAlive = true
      } else {
          //解决第一次不缓存问题
          if (from.name) {
            to.meta.keepAlive = false
          } else {
            to.meta.keepAlive = true
          }
        }
      }
      next()  
}      

3.list.vue

import { defineComponent, nextTick } from 'vue'
import { onBeforeRouteLeave } from 'vue-router'
export default defineComponent({
  name: 'list',
  setup() {
     onBeforeRouteLeave((to, from, next) => {
      //当即将访问的界面不是detail则销毁组件,以免上一次缓存信息存在
      const cacheList: any = ['detail']
      if (cacheList.indexOf(to.name) === -1) {
        //销毁缓存信息(vue3没有_this.$destory()方法,所以通过v-if实现组件的销毁)
       //vuex改变全局变量isRouterAlive的值
        _this.$store.commit('menu/changeRouterAlive', false)
        nextTick(() => {
          _this.$store.commit('menu/changeRouterAlive', true)
        })
      }
      next()
    })
  }
})      

3.总结:

   1.以上解决方法同样适用vue2,只需要改动一些代码用法即可;思路一样

   2.如果仅在beforEach中根据to.name判断是否为detail,来设置 keepAlive为true,当从list进入到其他页面,再从其他页面回到list  然后list在进入detail最后返回list。这个时候会缓存上上次的缓存记录

      因此需要当从离开list到非detail页面时,应销毁组件

      由于vue3.x不支持this.$detroy();因此通过改变isRouterAlive的值来实现组件的销毁  先设置false,再设置为true。即实现组件的重新渲染。即上一个组件被销毁

  3.遗留问题

继续阅读