vue2.0下嵌套路由keep-alive以及路由带参数时缓存解决方案

330 阅读1分钟

嵌套路由

路由一定只能嵌套一层children即只有一个router-view 要不切换其他层级的路由缓存会消失 原因:

  • 缓存是存储在children的route-view上的
  • 路由的component不能为空,当有时为了统一规范,需要一个空的component时,路由的component为这样写
<template>
  <keep-alive>
    <router-view />
  </keep-alive>
</template>
<script>
export default {
  name: "ParentView",
  data() {
    return {};
  },
  computed: {},
};
</script>

<style lang="less" scoped></style>

解决方案 直接将多余的route-view删除

  // 路由守卫,跳转后处理
  router.afterEach((to) => {
    handleKeepAlive(to);
  });

  
/**
 * 递归处理多余的 layout : <router-view>,
 * 让需要访问的组件保持在第一层 index : <router-view> 之下
 * @param to
 */
function handleKeepAlive(to) {
  if (to.matched && to.matched.length > 2) {
    for (let i = to.matched.length - 1; i >= 0; i--) {
      const element = to.matched[i];
      // 因为import()异步懒加载,第一次获取不到element.components.default.name , 所以不能再beforeEach做,不然第一次访问的界面不缓存第二次才会缓存
      // afterEach就不一样了,这时候可以获取到element.components.default.name了
      if (element.components.default.name === "ParentView") {
        to.matched.splice(i, 1);
      }
    }
  }
}

路由带参数时缓存无法删除

include 只有名称匹配的组件会被缓存(名称指的是组件中定义的name) 同一个组件的name是一样的,修改include时,如果name还存在那么就不会删除

解决方案 在tab页删除时手动删除缓存

<template>
<页签Tab组件  @删除页签="removeTab($event)"></页签Tab组件>

<keep-alive :include="cacheList">
    <router-view ref="routerView" :key="tabId" />
</keep-alive>

</template>

<script>

removeTab(tabId) {
    if (!this.$refs.routerView) {
        return;
    }

    let { cache, keys } =this.$refs.routerView.$vnode.parent.componentInstance;
    if (tabId in cache) {
            // 手动销毁组件
            cache[tabId].componentInstance.$destroy();
            cache[tabId].componentInstance = undefined;
            delete cache[tabId];
    }
    let index = keys.findIndex((a) => a == fullPath);
    if (index >= 0) {
        keys.splice(index, 1);
    }
}
</style>

实际使用发现delete cache[fullPath]没有生效,并不会删除object的key