Можно ли передать компонент в качестве реквизита и использовать его в дочернем компоненте в Vue?

В приложении Vue 2.0 скажем, что у нас есть компоненты A, B и C.

A объявляет, регистрирует и использует B

Можно ли передать C из A в B?

Что-то вроде этого:

<template>
  <div class="A">
    <B :child_component="C" />
  </div>
</template>

И используйте C в B как-то.

<template>
  <div class="B">
    <C>Something else</C>
  </div>
</template>

Мотивация: я хочу создать общий компонент B, который используется в A, но получает от A его дочерний элемент C. На самом деле A будет использовать B несколько раз, передавая ему "C".

Если этот подход неверен, каков его правильный способ в Vue?

Ответ на @Saurabh

Вместо того, чтобы проходить как реквизит, я попробовал предложение внутри B.

<!-- this is where I Call the dynamic component in B -->

<component :is="child_component"></component>

//this is what I did in B js
components: {
 equip: Equipment
}, 
data () {
 return {
   child_component: 'equip',
   _list: []
 }
}

В основном я пытаюсь отображать оборудование, но динамический путь

Я получаю 3 ошибки в консоли и пустую страницу

[Vue warn]: Ошибка при рендеринге компонента в /home/victor/projetos/tokaai/public/src/components/EquipmentFormItem.vue:

Uncaught TypeError: невозможно прочитать свойство 'name' из undefined

TypeError: Не удается прочитать свойство 'setAttribute' из undefined

Видимо, я что-то делаю неправильно

Ответ 1

Вы можете использовать специальный атрибут is для выполнения такого рода вещи. Пример динамического компонента и его использования можно найти здесь.

Вы можете использовать одну и ту же точку монтирования и динамически переключаться между несколькими компонентами, используя зарезервированный элемент, и динамически связываться с его атрибутом is:

Ваш код будет выглядеть следующим образом:

<template>
  <div class="B">
    <component :is="child_component"> Something else</component>
  </div>
</template>

Ответ 2

Подведение итогов:

<!-- Component A -->
<template>
  <div class="A">
    <B>
      <component :is="child_component"></component>
    </B>
  </div>
</template>

<script>
import B from './B.vue';
import Equipment from './Equipment.vue';

export default {
  name: 'A',
  components: { B, Equipment },
  data() {
    return { child_component: 'equipment' };
  }
};
</script>

<!-- Component B -->
<template>
  <div class="B">
    <h1>Some content</h1>
    <slot></slot> <!-- Component C will appear here -->
  </div>
</template>

Ответ 3

Здесь решение для пересылки пользовательского компонента через реквизиты другого компонента

:is является специальным атрибутом, и он будет использоваться для замены вашего фактического компонента, и он будет игнорироваться, если вы попытаетесь использовать его в качестве опоры в своем компоненте. К счастью, вы можете использовать что-то еще, например, el а затем переслать это component следующим образом:

<template>
  <div>
    <component :is="el">
      <slot />
    </component>
  </div>
</template>
<script>
  export default {
    name: 'RenderDynamicChild',
    props: {
        el: {
            type: [String, Object],
            default: 'div',
        },
    },
  }
</script>

Любой допустимый элемент, который вы используете в атрибуте el будет использоваться как дочерний компонент. Это может быть html или ссылка на ваш пользовательский компонент или div по умолчанию, как указано в объявлении компонента.

Передача пользовательского компонента в prop немного сложнее. Можно предположить, что вы объявляете в свойстве components родительского компонента, а затем используете его для атрибута el но это не работает. Вместо этого вам нужно иметь свой динамический компонент в data или computed свойстве, чтобы вы могли использовать его в шаблоне в качестве реквизита. Также обратите внимание, что AnotherComponent не нужно объявлять в свойстве components.

<template>
  <RenderDynamicChild :el="DynamicComponent">
    Hello Vue!
  </RenderDynamicChild>
</template>

<script>
import RenderDynamicChild from './DynamicChild';
import AnotherComponent from './AnotherComponent';

export default {
  name: "ParentComponent",
  components: { DynamicChild },
  data() {
    return {
      DynamicComponent: AnotherComponent,
    };
  },
};
</script>

Использование вычисляемого свойства для вашего динамического компонента позволяет вам легко переключаться между компонентами:

<script>
import DynamicChild from './DynamicChild';
import AnotherComponent from './AnotherComponent';

export default {
  name: "ParentComponent",
  components: { DynamicChild },
  data() { return { count: 0 } },
  computed: {
    DynamicComponent() {
      return this.count % 2 > 1 ? AnotherComponent : 'article';
    },
  },
};
</script>

Увеличьте this.count для this.count между AnotherComponent и простым HTML-элементом article.