vue3 keep-alive缓存 多层嵌套路由 onMounted多次触发及根据不同情况可能需刷新缓存页面的问题

1. onMounted多次触发

原因

一级路由找不到路由对应的route.meta.keepAlive,导出在访问一级路由和子路由都触发生命周期加载

解决方案

在外层router-view的时候,判断获取的route层级,如果不是一级目录则通过当前route获取后再使用,接口调用不要写在onMounted,需要写到onActivated中

一级页面代码

<router-view v-slot="{ Component, route }">
            <keep-alive>
              <component
                :is="Component"
                :key="getFirstLevelRoute(route).name"
                v-if="getFirstLevelRoute(route).meta.keepAlive"
              ></component>
            </keep-alive>
            <component
              :is="Component"
              :key="getFirstLevelRoute(route).name"
              v-if="!getFirstLevelRoute(route).meta.keepAlive"
            ></component>
          </router-view>
const getFirstLevelRoute = route => {
  if (!Array.isArray(route.matched) || route.matched.length === 0) {
    return route;
  }
  return route.matched[0];
};

子页面代码(正常缓存写法即可)

  <router-view v-slot="{ Component, route }">
   <keep-alive>
      <component :is="Component" :key="route.name" v-if="route.meta.keepAlive"></component>
   </keep-alive>
   <component :is="Component" :key="route.name" v-if="!route.meta.keepAlive"></component>
</router-view>

2. 优化缓存后页面一直不刷新问题(部分逻辑需要刷新)

例如:从菜单进入缓存列表页面需要刷新,但是从列表页面进入详情页后返回不需要刷新列表页

思路:
1、在路由中新增isBack字段用于判断是否需要刷新, 路由守卫出判断从那个页面进入的,不需要刷新改为true(例如详情),特殊情况也可以在地址中添加isRefresh参数控制(isRefresh==1需要刷新),实现同一个页面可根据不同的情况拼接isRefresh参数实现是否需要刷新缓存
2、不加入sessionStorage缓存会导致从详情切换到任意缓存列表页都不会请求数据,改进后只有返回跳转前的缓存页才不请求数据

路由守卫代码

router.beforeEach((to, from, next) => {
	var prevRouter = sessionStorage.getItem("prevRouter");
    if (from.meta.isDetail && !from.query.isRefresh && to.path == prevRouter) {
        to.meta.isBack = true
    } else {
        to.meta.isBack = false
    }
    
  	if (to.meta.keepAlive) {
        sessionStorage.setItem("prevRouter", to.path);
    }else if(!to.meta.isDetail){
        sessionStorage.setItem("prevRouter", "");
    }
    next()
})

页面路由

export default [
    {
        path: "/setting",
        name: "setting",
        meta: {
            transform: false,
        },
        children: [
            {
                path: "list",
                name: "list",
                meta: {
                    keepAlive: true
                },
                component: () => import("@/pages/app-settings/jiuchuang/notice-examine.vue")
            },
            
            {
                path: "detail",
                name: "detail",
                meta: {
                    isDetail: true
                },
                component: () => import("pages/app-settings/components/notice/notice-detail.vue")
            },
           
        ],
        component: () => import("pages/index.vue")
    },
]

列表页面代码

import { onActivated } from "vue";
onActivated(() => {
  // 调用时机为首次挂载以及每次从缓存中被重新插入时
  if (!route.meta.isBack) {
  	//获取列表数据
   	loadata()
  }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值