背景
有一种需求,我们需要根据组件的地址,动态加载组件。如何实现?
Vue 3 动态加载组件
假如我有一个组件(demoComp.vue
,地址为:@/views/starvas/pages/components/demoComp.vue
),如内容如下:
<template>
<div>
<span>{{ value }}</span>
</div>
</template>
<script setup>
const props = defineProps({
value: {
type: String,
required: false,
},
})
console.log(props.value)
</script>
如果我想在其他组件里动态引用它,可以这样写:
<template>
<div>
<Comp :value="va"></Comp>
</div>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
const Comp = defineAsyncComponent(() => import('@/views/starvas/pages/components/demoComp.vue'))
const va = ref('test')
</script>
更深一步
上面的写法没问题,但问题是,当我们的组件地址配置在后端时,不太可能提前知道。这时就需要再包一层,新写一个组件(名为: CompItem
):
<script setup>
import { computed, defineAsyncComponent } from 'vue'
const props = defineProps({
component: {
type: Object, // is props 两个属性
required: true
}
})
const is = computed(() =>
defineAsyncComponent(() => import(`${props.component.is}.vue`))
)
</script>
<template>
<component :is="is" v-bind="component.props" />
</template>
这样组件地址和参数都能通过传参解决,调用如下
<template>
<CompItem :component="comp"></CompItem>
</template>
<script>
import CompItem from '@/views/starvas/pages/components/CompItem.vue'
const comp = {
is: '/src/views/starvas/pages/components/demoComp',
props: {
value: "test",
}
}
</script>
这里要注意一点是,组件地址不能传@/views/starvas/pages/components/demoComp
这种以@开头的,要传全地址,否则会报如下错误:
![](https://img.haomeiwen.com/i297930/821fe8f41245c577.png)
原因是:vite
里做了个符号解析将@
转成全地址。
网友评论