Skip to main content
  1. About
  2. For Teams
Asked
Viewed 17k times
8

I am using Vue JS to make a list that has one generic list item component. If there exists a none generic component that meets the correct type a custom component will be used.

 <email-queue-item v-for="item in queue"
                          :key="item.id"
                          :item="item"
                          v-if="type == 'EmailMessage'"></email-queue-item>
        <queue-item v-for="item in queue"
                          :key="item.id"
                          :item="item"
                          v-else></queue-item>

The code above better illustrates what I am trying to do. The problem I seem to have is due loops first creating two list and then checks the conditional. Is there a way in due to pick the right component vase on the type and then loop through the list?

The data Used to display these components is like this:

{
    name: Email,
    type: EmailMessage,
    data:[
        {...},
        {...},
        ...
    ]
}
1
  • 1
    using v-bind:is, check dynamic component
    Sphinx
    –  Sphinx
    2018-05-18 20:26:52 +00:00
    Commented May 18, 2018 at 20:26

2 Answers 2

17

Dynamic components make this pretty easy in the template:

<component
    :is="type == 'EmailMessage' ? 'email-queue-item' : 'queue-item'"
    v-for="item in queue"
    :key="item.id"
    :item="item"
/>
Sign up to request clarification or add additional context in comments.

1 Comment

This works for me. Don't forget to import the components.
3

If I undersstand correctly, you'd like v-for with dynamic component.

so check Vue Official Guide: dynamic component, then the demo will be like below which uses v-bind:is:

Vue.config.productionTip = false
Vue.component('email-queue-item', {
  template: `<div><h3 :style="{'background-color':color}">Email: {{color}}</h3></div>`,
  props: ['color']
})
Vue.component('message-queue-item', {
  template: `<div><h1 :style="{'background-color':color}">Message: {{color}}</h1></div>`,
  props: ['color']
})
new Vue({
  el: '#app',
  data() {
    return {
      items: [
        {'component':'email-queue-item', 'color':'red'},
        {'component':'message-queue-item', 'color':'blue'},
        {'component':'email-queue-item', 'color':'green'}
      ]
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div v-for="(item, index) in items" :key="index" :color="item.color" :is="item.component"></div>
</div>

3 Comments

I don't think you really understand.I have a parent component called list which those two components are called in, and data is passed with a list type. If it is an email list type use email queue item otherwise use regular queue item.
The problem how it is right now is it is acting like I have to list and not one. This causes duplicate keys.
@JohnDoe, I don't understand what you said. probably you need: <div v-for="item in queue" :key="item.id"><email-queue-item :item="item" v-if="type == 'EmailMessage'"></email-queue-item> <queue-item :item="item" v-else></queue-item></div>

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.