1

Following case: I have an API outputting all the content for my Page, as well as its structure and so on (for better understanding, imaging an CMS which includes kind of a page builder, where an author can place components by drag and drop to generate pages content, which is delivered to the front-end by that api).

The structure of the api output would look something like:

{content: [
  {component: hero, content: {...} },
  {component: form, content: {...} },
  ...
]}

So to generate related content I would think of using dynamic components like:

<template v-for="item in content">
  <component :is="item.component" />
</template>

However, doing so I would face the problem, that I have to add properties data onto my components somehow, which (as far as I could see) isn't described within the Vue documentation. So now I wonder how to pass props onto dynamic components, which have entirely different props (hero might have an image, form could have input-placeholders, and so on) - any ideas???

2 Answers2

2

Take a look at v-bind https://v2.vuejs.org/v2/guide/components-props.html#Passing-the-Properties-of-an-Object (same as Vue 3).

Assuming your API includes a props property for each component, then you'd do this:

<component v-for="item in content" :is="item.component" v-bind="item.props"></component>
tony19
  • 125,647
  • 18
  • 229
  • 307
jordanfb
  • 539
  • 5
  • 9
0

Nowadays it's necessary to state what version of Vue do you work with.

With Vue 2 you could do it like this:

Vue.component('FirstComponent', {
  props: ['title', 'prop1_1'],
  template: `
    <div>
      {{ title }}<br />
      {{ prop1_1 }}
    </div>
  `
})

Vue.component('SecondComponent', {
  props: ['title', 'prop2_1', 'prop2_2'],
  template: `
    <div>
      {{ title }}<br />
      {{ prop2_1 }}<br />
      {{ prop2_1 }}
    </div>
  `
})

new Vue({
  el: "#app",
  data() {
    return {
      items: [
        {
          component: 'FirstComponent',
          props: {
            title: 'First component title',
            prop1_1: 'this is prop 1_1'
          },
        },
        {
          component: 'SecondComponent',
          props: {
            title: 'Second component title',
            prop2_1: 'this is prop 2_1',
            prop2_2: 'this is prop 2_2',
          },
        },
      ]
    }
  },
  template: `
    <div>
      <component
        v-for="(item, idx) in items"
        :key="idx"
        :is="item.component"
        v-bind="item.props"
      ></component>
    </div>
  `
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
muka.gergely
  • 8,063
  • 2
  • 17
  • 34
  • That only works if one has control over the data structure - otherwise one will have the caveat, that one can only pus one data object into a component, so a component can only have one single prop. right now it seems to me, that this is the only way to solve the problem. : / – Irgend Son Hansel Jan 04 '22 at 13:42
  • @IrgendSonHansel ? Sorry, but I don't really get the constraint you are talking about. You can pass in as many objects as you want: as an `Array` or spread it in a new `Object`. Both dynamic components in the snippet accept more than 1 prop. – muka.gergely Jan 04 '22 at 13:48