I'd like to know how I can iterate a list of component names (which come from an AJAX call to an API server) and render them as components, and pass relevant properties to each component (i.e. bind their properties dynamically).
So far I have managed to iterate a JSON list of items that represent components, and successfully render these components. What I'd like to do now is bind the properties for each component using v-bind
.
In the example below, the item-one
component would receive the image
property with the item1.jpg
value; and the item-two
component wouldn't receive any properties.
<template>
<div v-for="item in items">
<component :is="Object.keys(item)[0]" :v-bind="???"></component>
</div>
</template>
<script>
import ItemOne from '../components/item-one'
import ItemTwo from '../components/item-two'
export default {
components: {
ItemOne,
ItemTwo
},
asyncData () {
return {
items: [
{ 'item-one': { 'image': 'item1.jpg' } },
{ 'item-two': { } }
]
}
}
}
</script>
I tried using :v-bind="Object.values(Object.keys(item)[0])"
but I get the attribute v-bind="[object Object]"
in the rendered element.
First, you need to get rid of the colon before v-bind
. The colon is a short-hand for v-bind
when prefixed to an attribute. But, when passing an object of key pairs to bind, you simply use the v-bind
directive.
Second, you are not correctly referencing the properties of each item. You can reference them like this:
v-bind="item[Object.keys(item)[0]]"
You wouldn't need to use Object.keys
if you changed the structure of your items
property a bit:
items: [{
type: 'item-one',
props: { 'image': 'item1.jpg' },
}, {
type: 'item-two',
}]
This way, by explicitly labeling the component type and properties beforehand, your template would be much easier to understand:
<div v-for="item in items">
<component :is="item.type" v-bind="item.props"></component>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With