我有一个元素的数据结构,如:
[
{
type: 'text',
content: 'some text'
},
{
type: 'image',
content: {
name: 'filename.jpg',
url: 'http://example.com/filename.jpg'
}
}
]
在我的模板中,我使用if进行v-for以根据类型呈现不同的组件:
<div v-for="element in elements">
<div v-if="element.type === 'text'">
<p>{{ element.content }}</p>
</div>
<div v-if="element.type === 'image'">
<some-component :image="element.content"></some-component>
</div>
</div>
我的问题是,有没有“更清洁”,更好的方法呢?
答案 0 :(得分:1)
我想我会根据<component>标签创建一个组件交换器 - 比如:
// template swapper based on the <component> tag
// :is - string value pointing to the component to be used
// :value - data to be used in the selected component
Vue.component('vue-html-tag', {
props: ['value'],
template: `<component :is="'vue-' + value.tag + '-tag'" :value="value"></component>`
});
// tag components
Vue.component('vue-p-tag', {
props: ['value'],
template: `<p :class="value.class">
{{ value.text }}
<vue-html-tag v-for="item in value.content" :key="item.id" :value="item"></vue-html-tag>
</p>`
});
Vue.component('vue-img-tag', {
props: ['value'],
template: `<img :src="value.src" />`
});
Vue.component('vue-a-tag', {
props: ['value'],
template: `<a :href="value.href" :target="value.target">{{ value.text}}</a>`
});
Vue.component('vue-span-tag', {
props: ['value'],
template: `<span :class="value.class">
{{ value.text }}
<vue-html-tag v-for="item in value.content" :key="item.id" :value="item"></vue-html-tag>
</span>`
});
// app instance
new Vue({
el: '#app',
data: {
html: [
{ id: 1, tag: 'p', text: 'Lorem ipsum', class: 'foo',
content: [
{ id: 11, tag: 'span', text: 'Nested span:', class: 'foo-span',
content: [
{ id: 111, tag: 'a', text: 'Link 1 inside span inside p', href: 'http://example.com' },
{ id: 112, tag: 'a', text: 'Link 2 inside span inside p', href: 'http://example.com' },
]
}]
},
{ id: 2, tag: 'img', src: 'http://via.placeholder.com/350x150' },
{ id: 3, tag: 'a', text: 'Link', href: 'http://example.com' }
]
}
})
&#13;
.foo {
padding: 10px;
border: 1px solid olive
}
.foo-span {
padding: 20px;
display: block;
border: 1px solid orange
}
.foo-span a {
display: block;
padding: 10px;
margin-bottom: 5px;
border: 1px solid tomato
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
<div id="app">
<vue-html-tag v-for="item in html" :key="item.id" :value="item"></vue-html-tag>
</div>
&#13;