philipsadman
philipsadman

Reputation: 37

How can I set custom template for item in list and than use it inside `v-for` loop?

What I want to achieve is something like:

<li v-for="(item, index) in items" :key="index>
  <div v-if="item.Component">
    <item.Component :value="item.value" />
  </div>
  <div v-else>{{ item.value }}</div>
</li>

But anyway I don't like at all this solution. The idea of defining Component key for an item in items list is hard to maintain since at least it is hard to write it in template-style way (usually we are talking about too long HTML inside). Also I don't like to wrap item.Component inside div.

data() {
  return {
    list: [{
      value: 'abc',
      Component: {
        props: ['value'],
        template: `123 {{ value }} 312`
      }
    }]
  };
}

Does anyone know the best-practice solution for this and where Vue describes such case in their docs?

Upvotes: 0

Views: 958

Answers (1)

Blackraspberryyy
Blackraspberryyy

Reputation: 2134

You can use Vue's <component/> tag to dynamically set your component in your list.

<li v-for="(item, index) in items" :key="index>
  <component v-if="item.Component" :is="item.Component" :value="item.value"></component>
  <div v-else>{{ item.value }}</div>
</li>

<script>
  ...,
  data: () => ({
    list: [{
      value: 'abc',
      Component: {
        props: ['value'],
        template: `<div>123 {{ value }} 312</div>` // must be enclosed in a element.
      }
    }]
  })
</script>

You can also import a component too so you can create a new file and put your templates and scripts there.

Parent.vue

<script>
import SomeComponent from "@/components/SomeComponent.vue";  //import your component here.

export default {
  data() {
    return {
      list: [
        {
          value: "abc",
          Component: SomeComponent  // define your imported component here.
        },
      ]
    };
  }
};
</script>

SomeComponent.vue

<template>
  <div>123 {{ value }} 312</div>
</template>
<script>
export default {
  name: "SomeComponent",
  props: ["value"]
};
</script>

Here's a demo.

Upvotes: 1

Related Questions