记一次vue3.2中动态组件加载

1,515 阅读1分钟

记一次vue3.2中动态组件加载

<component
        :key="componentName"
        :is="componentName"
        :ref="componentName"
 ></component>
//动态加载以下的三个组件
import MenuDetail from "./components/menu-detail.vue";
import MenuAdd from "./components/menu-add.vue";
import MenuEdit from "./components/menu-edit.vue";
​
//方式一
//简单粗暴
const componentName = ref()   
componentName.value = MenuDetail
....
//这种写法在开发环境中会警告,但不会报错,也能用,但在生产环境下会直接报错
 runtime-core.esm-bundler.js:38 [Vue warn]:Missing ref owner context. ref cannot be used on hoisted vnodes. A vnode with ref must be created inside the render function. 
//这个警告是因为ref不是一个正确的类型引起的,因为componentName是一个组件//方法二
 const componet = {
     MenuDetail,
     MenuAdd,
     MenuEdit
 }
 const componentName = shallowRef()  //是为了解决另外一个警告
 //使用 shallowRef 这个api,而不是 ref,是为了处理异常 Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with markRaw or using shallowRef instead of ref.。我们这里使用浅代理即可,不需要使用深层代理,这样做可以提供性能。
​
 componentName.value = componet['MenuDetail']  //和第一种方法一样,治标不治本,ref同样是一个组件,不是字符串//方法三
//我们需要将componentName变成一个字符串,但是is要是一个组件
<component
        :key="componentName"
        :is="dialogComponents.get(componentName)"
        :ref="componentName"
></component>
const componentName = ref('') //保存需要加载的的组件名称
const dialogComponents = ref(new Map<string, any>())
dialogComponents.value.set(
    'MenuDetail',
    defineAsyncComponent(() => import('./components/menu-detail.vue'))
)
dialogComponents.value.set(
    'MenuAdd',
    defineAsyncComponent(() => import('./components/menu-add.vue'))
)
dialogComponents.value.set(
    'MenuEdit',
    defineAsyncComponent(() => import('./components/menu-edit.vue'))
)