我想在vuejs CLI中动态加载组件作为单个文件组件, 在ajax请求之前,我不知道将加载哪个组件,也无法在页面加载时加载150个组件。
以下是ajax响应的示例:
[
{is="Title", text:"Hello World"},
{is:"Status", type:"info", text:"Look at these beautiful photos"},
{is:"Carousel", imgs:["/img/1.jpg","/img/2.jpg","/img/3.jpg"]},
{is:"Status", type:"alert", text:"These images are the property of the creator"},
]
我想要一个渲染如下的vue组件:
<template>
<component is="Title" text="Hello World"/>
<component is="Status" type="info" text="Look at these beautiful photos"/>
<component is="Carousel" imgs="['/img/1.jpg','/img/2.jpg','/img/3.jpg']"/>
<component is="Status" type="alert", text="These images are the property of the creator"/>
</template>
<script>
import Title from '@/components/libs/Title.vue'
import Status from '@/components/libs/Status.vue'
import Carousel from '@/components/libs/Carousel.vue'
export default {
components: {
Title,
Status,
Carousel
},
}
</script>
答案 0 :(得分:2)
App.vue
<template>
<div id="app">
<DynamicComponentSet :definition="response"/>
</div>
</template>
<script>
import DynamicComponentSet from "@/components/DynamicComponentSet";
export default {
name: "App",
components: {
DynamicComponentSet
},
data() {
return {
response: [
{ is: "Title", text: "Hello World" },
{ is: "Status", type: "info", text: "Look at these beautiful photos" },
{ is: "Carousel", imgs: ["/img/1.jpg", "/img/2.jpg", "/img/3.jpg"] },
{
is: "Status",
type: "alert",
text: "These images are the property of the creator"
}
]
};
}
};
</script>
DynamicComponentSet.vue
<template>
<div>
<component v-for="(comp, index) in definition" :key="index" v-bind="comp" :is="comp.is"/>
</div>
</template>
<script>
export default {
name: "DynamicComponentSet",
components: {
Title: () => import("@/components/Title.vue"),
Status: () => import("@/components/Status.vue"),
Carousel: () => import("@/components/Carousel.vue")
},
props: {
definition: Array
}
};
</script>
注1:必须在is
中指定所有可能的components
值。组件按需加载(async components)。
注2:所有response
对象的属性都使用props as an object语法通过v-bind="comp"
传递到各个组件中,因此数据属性名称/类型必须与每个组件属性匹配。 / p>
注3:实际上:is="comp.is"
并不需要使它起作用,因为is
与其他道具一起被传递了。我补充说只是为了让ESLint开心...
答案 1 :(得分:1)
您可以像下面这样用world.cities
包装它们,而不是直接导入组件
这只会在实际需要时从服务器加载(从服务器)
import
答案 2 :(得分:1)
不是使用计算的方法动态导入组件。
computed: {
Title() {
return () => import('@/components/libs/Title.vue');
},
Status() {
return () => import('@/components/libs/Status.vue');
}
},
在模板中
<component v-bind:is="Title"></component>
<component v-bind:is="Status"></component>
答案 3 :(得分:0)
响应将始终包含那些字段吗?您要在ajax请求之前加载组件吗?喜欢默认值吗?
父组件
<template>
<CustomComponent :responseData="Title" />
</template>
<script>
import CustomComponent from '@/components/libs/CustomComponent.vue'
export default {
components: {
CustomComponent
},
data() {
return {
responseData: null, // populate this with ajax response
}
}
}
</script>
CustomComponent
<template>
<div> <!-- components should only have one root element so wrap in a div -->
<p v-if="response.text">{{ response.text }}</p>
<p type="info">Look at these beautiful photos<p/>
<!-- etc. etc. -->
</div>
</template>
<script>
import Status from '@/components/libs/Status.vue'
import Carousel from '@/components/libs/Carousel.vue'
export default {
props: {
responseData: {
text: 'default text', // these defaults allow you to load before the ajax response comes in
images: ['/img/1.jpg','/img/2.jpg','/img/3.jpg'],
}
},
components: {
Status,
Carousel
},
}
</script>