vue3 多个路由指向同一个页面动态修改组件name,keep-alive独立缓存

392 阅读1分钟

前情提要:公司后台管理系统中有个需求是新增和修改打开一个新的页面,而这俩路由用的都是同一个组件,这就导致如果给组件直接添加name的话就会互相影响

刚开始对keep-alive不了解,以为修改路由里面的name就行了,发现并不可行,路由的name需与组件的name一致,否则不能达到缓存的效果。然后网上找了挺多方法都是在keep-alive组件哪里写个方法重新生成组件,但这个方法对我无用,应该是因为组件已经在router添加进去了。

最后找到下面方法,在动态添加路由的时候把组件重写 添加name

import { defineComponent, onBeforeMount, resolveComponent, shallowRef } from "vue";

/**
 * 将指定组件设置自定义名称
 *
 * @param {String} name 组件自定义名称
 * @param {Component | Promise<Component>} component
 * @return {Component}
 */
export default function createCustomComponent(name, component) {
  return defineComponent({
    name,
    setup() {
      const resolvedComponent = shallowRef(null);

      const loadComponent = async () => {
        try {
          let mod;
          if (component instanceof Promise) {
            mod = await component;
          } else {
            mod = component;
          }
          resolvedComponent.value = resolveComponent(mod?.default || mod);
        } catch (error) {
          console.error(`can not resolve component ${name}, error:`, error);
        }
      };

      onBeforeMount(loadComponent);

      return () => {
        return resolvedComponent.value ? h(resolvedComponent.value) : null;
      };
    },
  });
}

使用方式就是在需要用到的页面引入 然后传入自定义name和组件路径

import createCustomComponent from '@/utils/createCustomComponent'

// 添加路由前使用
// name: 自定义组件name 示例:route.name
// path: 组件路径 示例:import('@/views/test/add')
route.component = createCustomComponent(name, path)


import createCustomComponent from '@/utils/createCustomComponent'

// 路由name需与组件的name一致,否则不能达到缓存的效果。
{
    path: "test/add",
    hidden: true,
    component: createCustomComponent('AddName', import('@/views/test/add')),
    name: "AddName",
    meta: { title: "", icon: "", noCache: false },
},