1.现象:二级菜单开启菜单缓存后页面正常缓存,但是三级菜单开启缓存后,缓存时而有效时而无效。

2.踩坑日记

1.踩坑1:

配置菜单时只将三级菜单得缓存开启了,二级菜单、一级菜单都未开启

所以老老实实 开启父级缓存开关.

2.踩坑2.

配置二级菜单时因为该二级菜单没有具体页面他只是承接上下级组件得作用所以二级菜单得组件布局也使用了和一级菜单一样得布局,导致含有keepalive得组件重复渲染即一级菜单渲染了一回二级菜单又keepalive 一回,那这缓存肯定不会起作用啊

一级菜单布局组件 routerView.vue

<template>
  <div class="main">
    <keep-alive :include="includedComponents">
      <router-view v-if="keepAlive" :key="$route.fullPath" />
    </keep-alive>
    <router-view v-if="!keepAlive" />
  </div>
</template>

<script>
  import Vue from 'vue'
  import { CACHE_INCLUDED_ROUTES } from "@/store/mutation-types"

  export default {
    name: "RouteView",
    computed: {
    
      includedComponents() {
        const includedRouters = Vue.ls.get(CACHE_INCLUDED_ROUTES)
        return includedRouters;
      },
    
      keepAlive () {
  
        return this.$route.meta.keepAlive
      }
    },
  }
</script>

解决办法:新建一个页面(jeecg 已经帮忙建好了)只用来承接上下级组件得BlanckLayout.vue  代码如下:

<template>
  <div>
    <router-view />
  </div>
</template>

<script>

  export default {
    name: "BlankLayout",
  }
</script>

<style scoped>

</style>

 所以二级菜单配置如下,这样就不会重复渲染 routerView 里面得keepalive 啦~

踩坑三:该配置得都配置好了,但是三级缓存还是时好时坏,原因不明,百度了一番查到了 ,要改路由拦截器通过to.matched  (挖坑中敬请期待)

router.beforeEach((to, from, next) => {
    if (to.matched && to.matched.length > 3) {
       for (let i = 0; i < to.matched.length; i++) {
         const element = to.matched[i]
         if (element.components.default.name === 'BlankLayout') {  //BlankLayout 二级菜单组件名称
           to.matched.splice(i, 1)
         }
       }
     }

})

链接在这自己看

本以为都走到这了 缓存失效的问题怎么也该好了,结果随便点了点还是时好时坏 摸不到头脑。准备放弃一波。不甘心又百度了一下啊 搜了搜 嘿嘿找到了问题发生在哪

继续踩坑:步骤三的问题 是因为 首次加载页面的时候 to.matched[i]里面获取不到components.default.name。所以进入不到判断逻辑里。

所以应该更换判断条件,缓存所有含有三级菜单的二级菜单名称,如果二级菜单的组件是balckLayout 就把该二级菜单的name 缓存起来用来判断。

具体步骤:这得细细得讲,这是我自己写得 上面都是找百度翻出来得 嘿嘿!

首先在获取菜单列表得接口里增加逻辑 递归获取含三级菜单的二级菜单name

代码如下:

// util.js 递归获取含有三级菜单得二级菜单名称
export function fullpage(menuData, selectedKey, blankPages) {
  for (let item of menuData) {
    if (item.component === selectedKey) {
      blankPages.push(item.name)
    } else if (Array.isArray(item.children)) {
      fullpage(item.children, selectedKey, blankPages)
    }
  }



  // 缓存含有三级菜单的二级菜单名称数组
  //获取菜单权限列表接口里
  queryPermissionsByUser().then(response => {
          let routeList = response.result.menu;
          let saveBlankPages = []
          fullpage(menuData, 'layouts/BlankLayout', saveBlankPages);
          sessionStorage.setItem(SAVE_BLANK_PAGES, JSON.stringify(saveBlankPages));
  })

拿到二级菜单name 数组后 去路由拦截器里更改判断逻辑 如下:

router.beforeEach((to, from, next) => {
  let saveBlankPages = JSON.parse(sessionStorage.getItem(SAVE_BLANK_PAGES) || "[]");
  if (to.matched && to.matched.length > 3) {
    for (let i = 0; i < to.matched.length; i++) {
      const element = to.matched[i]
      //废弃原因:清理缓存后首次加载页面 该页面的element.components.default.name 为空导致首次缓存页面失效 更换为使用element.name 进行判断
      // if (element.components.default.name === 'BlankLayout') {
      //   to.matched.splice(i, 1)
      // }

      const Index = saveBlankPages.findIndex((item) => { return item === element.name })
      if (Index >= 0) {
        to.matched.splice(i, 1)
      }
   
    }
  }

参考文章

参考文章很重要哦

GitHub 加速计划 / vu / vue
108
18
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
9e887079 [skip ci] 1 年前
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 1 年前
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐