1、父组件 index.vue
defineAsyncComponent 是 Vue3 的异步挂载
<template>
<div v-for="v in nav_items" :key="v.text">
<son :nav_text="v.text" :nav_component="v.nav_component"></son>
</div>
</template>
<script setup>
import { defineAsyncComponent, reactive } from "vue";
// 子组件
import son from "./son.vue";
let nav_items = reactive([
{
'text': '文字',
'nav_component': defineAsyncComponent(() => import("@/components/grandson.vue")) // 孙组件
}
])
</script>
2、子组件 son.vue
使用 is 动态引入组件,用法:
<component :is="grandson"></component>
最终会变成:
<grandson></grandson>
<template>
<div class="level1_item">
<span class="level1_text">{{props.nav_text}}</span>
<!-- 动态引入组件 -->
<component :is="props.nav_component"></component>
</div>
</template>
<script setup>
import { defineProps } from "vue";
// 父组件传入的 导航第一级 图片及文字
let props = defineProps({
nav_text: {
type: String,
default: () => {
return null;
}
},
nav_component: {
type: Object, // ⚠️注意是对象
default: () => {
return null;
}
},
})
</script>
3、孙组件 grandson.vue
<template>
<div>
123
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
⚠️注意
若出现警告(如下图):
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`.
Component that was made reactive: {name: 'AsyncComponentWrapper', __asyncLoader: ƒ, setup: ƒ}
解决方案 :
在第1步父组件 index.vue 里引入 shallowRef :
import { shallowRef } from "vue";
然后将 nav_component 修改为:
nav_component: shallowRef(defineAsyncComponent(() => import("@/components/grandson.vue")))