Reputation: 394
I currently have a v-for
which creates a list of components depending on an array of name values.
Depending on the step === 'name'
check, I'm displaying the relevant component. This method requires that I list every single possible component with a v-if
and I think there should be a cleaner way to accomplish this.
<div v-for="(step, idx) in steps" :key="idx">
<div v-if="step === 'url'">
<Goto @removeStep="removeStep(idx)" />
</div>
<div v-if="step === 'click'">
<Click @removeStep="removeStep(idx)" />
</div>
<div v-if="step === 'search'">
<Search @removeStep="removeStep(idx)" />
</div>
...
</div>
I'd rather interpolate the component directly in my for loop.
For example, something like...
<div v-for="(step, idx) in steps" :key="idx">
<[step.component] @removeStep="removeStep(idx)" :title="step.title" />
</div>
My array of dynamic components would then look like:
steps: [
{
component: 'Goto',
title: 'Go to Url'
},
{
component: 'Click',
title: 'Click Something'
}
]
I do not want to have all component options in a single file component, and prefer them to remain as separate components as I have currently.
Could I accomplish the above using either some form of interpolation or a computed prop perhaps?
Upvotes: 4
Views: 3353
Reputation: 138226
Vue supports dynamic components with <component is="COMPONENT_NAME">
. You could register your components locally, and then bind <component>.is
to the component names in your steps
array:
<template>
<div>
<component
:is="step.component"
v-for="(step, idx) in steps"
:key="step.component"
:title="step.title"
@remove-step="removeStep(idx)"
/>
</div>
</template>
<script>
import Goto from './components/Goto'
import Click from './components/Click'
import Search from './components/Search'
export default {
components: {
Goto,
Click,
Search,
},
data() {
return {
steps: [
{
component: 'Goto',
title: 'Go to Url',
},
{
component: 'Click',
title: 'Click Something',
},
{
component: 'Search',
title: 'Search the Internet',
},
],
}
},
methods: {
removeStep(idx) {
console.log('remove step', idx)
},
},
}
</script>
Upvotes: 6