vue-admin-box icon indicating copy to clipboard operation
vue-admin-box copied to clipboard

3级菜单的缓存不生效

Open qiguoqiang opened this issue 4 years ago • 4 comments

缓存只在二级页面生效,3级就失效了

qiguoqiang avatar Aug 27 '21 12:08 qiguoqiang

这个项,是一个已知的BUG,暂时还没想到好的解决方案,好像社区里面也没有好的解决方案,如果有,可以推荐一下

cmdparkour avatar Aug 27 '21 15:08 cmdparkour

@cmdparkour 我目前用这种方式可以缓存,可以参考下 在beforeEach的时候把三级的router-view移除掉,让子级的页面在父级的router-view上生效, 子级必须调用一个统一的名称的router-view,我设置的叫$TransitView

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

<script lang="ts">
  import { defineComponent } from 'vue'
  export default defineComponent({
    name: '$TransitView',
  })
</script>

然后在router中跳转前处理掉

// 解决嵌套router-view缓存失效的问题
async function handleKeepAlive(to) {
  if (to?.matched?.length > 2) {
    for (let i = 0; i < to.matched.length; i++) {
      const element = to.matched[i]
      if (element.components.default.name === '$TransitView') {
        to.matched.splice(i, 1)
        await handleKeepAlive(to)
      }

      // 如果有按需加载则等待加载完成
      if (typeof element.components.default === 'function') {
        await element.components.default()
        await handleKeepAlive(to)
      }
    }
  }
}

router.beforeEach((to, _from, next) => {
  handleKeepAlive(to)
  NProgress.start()
  if (store.state.user.token || whiteList.indexOf(to.path) !== -1) {
    to.meta.title ? changeTitle(to.meta.title) : '' // 动态title
    next()
  } else {
    next('/login') // 全部重定向到登录页
    to.meta.title ? changeTitle(to.meta.title) : '' // 动态title
  }
})

最后需要注意createNode文件中需要排除$TransitView这个名称的组件,否则会冲突


export function createNameComponent(component: any) {
  return () => {
    return new Promise((res) => {
      component().then((comm: any) => {
        const name =
          comm.default.name === '$TransitView' ? comm.default.name : `PageContainer${Date.now()}`
        const tempComm = defineComponent({
          name,
          setup() {
...


qiguoqiang avatar Aug 28 '21 11:08 qiguoqiang

@cmdparkour我目前用这种方式可以把缓存,可以参考下 在之前每个时候三级的路由器视图清除掉,让子级的在父级的路由器视图上生效,子级必须调用一个统一的名称的router-view,我设置的叫$TransitView

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

<script lang="ts">
  import { defineComponent } from 'vue'
  export default defineComponent({
    name: '$TransitView',
  })
</script>

然后在router中跳转前处理掉

// 解决嵌套router-view缓存失效的问题
async function handleKeepAlive(to) {
  if (to?.matched?.length > 2) {
    for (let i = 0; i < to.matched.length; i++) {
      const element = to.matched[i]
      if (element.components.default.name === '$TransitView') {
        to.matched.splice(i, 1)
        await handleKeepAlive(to)
      }

      // 如果有按需加载则等待加载完成
      if (typeof element.components.default === 'function') {
        await element.components.default()
        await handleKeepAlive(to)
      }
    }
  }
}

router.beforeEach((to, _from, next) => {
  handleKeepAlive(to)
  NProgress.start()
  if (store.state.user.token || whiteList.indexOf(to.path) !== -1) {
    to.meta.title ? changeTitle(to.meta.title) : '' // 动态title
    next()
  } else {
    next('/login') // 全部重定向到登录页
    to.meta.title ? changeTitle(to.meta.title) : '' // 动态title
  }
})

最后需要注意createNode文件中需要解决$TransitView这个名称的组件,否则会发生冲突


export function createNameComponent(component: any) {
  return () => {
    return new Promise((res) => {
      component().then((comm: any) => {
        const name =
          comm.default.name === '$TransitView' ? comm.default.name : `PageContainer${Date.now()}`
        const tempComm = defineComponent({
          name,
          setup() {
...

太帅了兄弟,完美解决

jkhrdhr avatar Jul 21 '22 11:07 jkhrdhr