Компоненты и подкомпоненты

Я новичок в Vue.js, и у меня возникли проблемы с использованием компонентов с подкомпонентами. У меня есть следующие .vue файлы

app.vue

<template>
  <section>
    <menu></menu>
    <h1>Create Your MIA</h1>
    <div id="board"></div>
    <slider>
      <skin></skin>
    </slider>
  </section>
</template>

slider.vue

<template>
  <div id="slider-panel">
    <h3>{{* heading}}</h3>
    <div class="slider">
      <slot>
        Some content
      </slot>
    </div>
  </div>
</template>

<script>
import skin from "./skin";
  export default {
    components: {
      skin: skin
    }
  };
</script>

skin.vue

<template>
    <div v-for="colour in colours">
      <div :style="{ backgroundColor: colour }">
        <img src="../assets/images/MIA.png"/>
      </div>
    </div>
</template>

<script>
  export default {
    data() {
      return {
        heading: "Choose Skin Tone"
      };
    }
  };
</script>

Я пытаюсь загрузить в компонент субкомпонент кожи. Все работает хорошо, за исключением субкомпонента скина, поскольку он не компилируется. Однако я не получаю никаких ошибок, связанных с компиляцией или vue. Я также хотел иметь несколько экземпляров компонента слайдера, подобного этому

app.vue

<template>
  <section>
    <menu></menu>
    <h1>Create Your MIA</h1>
    <div id="board"></div>
    <slider>
      <skin></skin>
    </slider>
    <slider>
      <foo></foo>
    </slider>
    <slider>
      <bar></bar>
    </slider>
  </section>
</template>

Я не уверен, что делаю не так.


person KArneaud    schedule 09.08.2016    source источник


Ответы (2)


Я не уверен на 100% в том, чего вы хотите здесь достичь, но чтобы скомпилировать компонент внутри компонента, вам нужно добавить дочерний компонент внутри родительского шаблона, например:

Slider.vue (я упростил структуру):

<template>
  <div id="slider-panel">
    <h3>{{* heading}}</h3>
    <skin></skin>
  </div>
</template>
<script>
import skin from './skin'
export default {
  components : {
    'skin': skin
  }
}
</script>

App.vue:

<template>
  <section>
    <menu></menu>
    <h1>Create Your MIA</h1>
    <div id="board"></div>
    <slider></slider>
  </section>
</template>

На самом деле, если вы добавляете skin в шаблон приложения внутри, чтобы добавить его в шаблон компонента slider, он включается (и отображается) при условии, что его область действия равна app, а не slider. Чтобы добавить skin в область slider, его необходимо добавить в шаблон slider. Проверьте это: https://vuejs.org/guide/components.html#Compilation-Scope < / а>

Еще кое-что:

Удачи!

Обновление:

Если вы хотите, чтобы компонент slider не зависел от содержимого и мог вставлять в него все, что захотите, у вас есть два варианта (которые я могу придумать):

  1. Удалите всю логику из компонента slider и сделайте skin потомком app. Затем используйте слоты в компоненте slider следующим образом:

Slider.vue:

<template>
  <div id="slider-panel">
    <h3>{{* heading}}</h3>
    <slot></slot>
  </div>
</template>
<script>
export default {}
</script>

App.vue:

<template>
  <section>
    <menu></menu>
    <h1>Create Your MIA</h1>
    <div id="board"></div>
    <slider>
      <skin></skin>
    </slider>
  </section>
</template>
<script>
import skin from './skin'
export default {
  skin: skin
}
</script>
  1. Если вы знаете, что внутри слайдера всегда будет закрытый набор компонентов, вы можете использовать динамические компоненты: https://vuejs.org/guide/components.html#Dynamic-Components
person Hector Lorenzo    schedule 10.08.2016
comment
Спасибо за предложение. Я разделил компонент skin и компонент slider, потому что хотел иметь возможность повторно использовать компоненты слайдера и заменить skin на что-то другое, например. <slider><foo></foo></slider> Смогу ли я выполнить это без дублирования компонента-слайдера? - person KArneaud; 10.08.2016
comment
Почему вы сказали потомок app.vue, а не дочерний компонент? - person KArneaud; 10.08.2016
comment
Нет причин, но вы правы, дочерний компонент имеет больше смысла. - person Hector Lorenzo; 10.08.2016
comment
Хм ... Я просматриваю код и не думаю, что он сработает, так как я хочу запустить несколько slider-components в компоненте app.vue - person KArneaud; 10.08.2016
comment
Это должен быть принятый ответ. +1 за предложение ... hyphen-separated name for the components. - person iusting; 01.05.2018

После некоторого исследования я обнаружил this, который относится к атрибуту is=, который будет включать шаблон подкомпонента

так что в app.vue

<slider-component>
      <div is="skin-component" v-for="colour in colours"></div>
    </slider-component>

а затем добавьте дочерние компоненты

person KArneaud    schedule 10.08.2016
comment
На самом деле это хорошая идея. Сообщите мне, работает ли он должным образом. - person Hector Lorenzo; 10.08.2016
comment
это сделал @HectorLorenzo - person KArneaud; 18.02.2017