Как иметь косвенно вложенные компоненты в Vue JS 2?

Мне удается создавать непосредственно самовложенные компоненты, используя свойство name, и все работает отлично.

<template>
    <div>
        <span>Hi, I'm component A!</span>
        <component-a></component-a>
    </div>
</template>

<script>
    export default {
        name: 'component-a',
        components: {
            'component-a': this
        }
    }
</script>

Теперь я хочу создать косвенно вложенные компоненты. Что-то вроде этого:

ComponentA.vue:

<template>
    <div>
        <span>Hi, I'm component A!</span>
        <component-b v-if="hasItems" v-for="item in items" :item="item"></component-b>
    </div>
</template>

<script>
    import ComponentB from './ComponentB.vue'

    export default {
        name: 'component-a',
        components: {
            'component-b': ComponentB
        },
        props: ['items'],
        computed: {
            hasItems() {
                return this.items.length > 0
            }
        }
    }
</script>

ComponentB.vue:

<template>
    <div>
        <span>Hi, I'm component B!</span>
        <component-a v-if="hasItems" :items="item.items"></component-a>
    </div>
</template>

<script>
    import ComponentA from './ComponentA.vue'

    export default {
        name: 'component-b',
        components: {
            'component-a': ComponentA
        },
        props: ['item'],
        computed: {
            hasItems() {
                return this.item.items.length > 0
            }
        }
    }
</script>

Но это не удается. Я получаю следующую ошибку:

[Предупреждение Vue]: не удалось смонтировать компонент: шаблон или функция рендеринга не определены. (находится в компоненте)

Кто-нибудь сталкивался с чем-то подобным и смог это решить? Согласно документации, у нас есть управляющие рекурсивные компоненты с условным рендерингом, что я делаю ... Я даже пытался использовать опору name для компонентов, но ничего не сделал (и я не думаю, что должен, поскольку компоненты не являются непосредственно самовложенными. ).


person António Quadrado    schedule 22.10.2016    source источник


Ответы (2)


Я попробовал ваш код и тоже получил ту же ошибку, не зная, что делать дальше. Позже я закрыл свой vue-cli и попытался напрямую использовать vue.js из CDN (автономная версия), и это сработало.

Вот рабочий пример: https://jsfiddle.net/mani04/z09Luphg/

Здесь нет никакого волшебства. Component A и Component B называют друг друга counterValue. Как только counterValue достигает некоторого предела, рекурсия останавливается.

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

РЕДАКТИРОВАТЬ: подробнее ниже

В ходе дальнейшего исследования сегодня я наткнулся на это обсуждение на github циклического импорта / циклических зависимостей webpack: https://github.com/webpack/webpack/issues/1788

Приведенный выше пример автономного jsFiddle не требует импорта ES6. В моем примере кода Vue.js регистрирует компоненты глобально перед запуском приложения. Поэтому он работает без проблем.

Таким образом, это не похоже на проблему с Vue.js, а на ограничение webpack / es6, основанное на текущей информации. Я могу ошибаться, продолжайте исследовать дальше!

person Mani    schedule 22.10.2016
comment
Я проанализировал предоставленную вами ссылку, и мне кажется, что проблема действительно связана с webpack и с тем, как обрабатывается циклический импорт. Но мне не удалось найти решение или обходной путь ... Я обновил laravel-elixir-webpack-official до последней версии и попробовал некоторые вещи, на которые есть ссылка в ссылке, но правда в том, что мой веб-пакет знания не очень глубокие, и у меня кончились варианты. Я буду продолжать пытаться понять, что происходит, и опубликую здесь, когда к чему-то приду. Если тем временем вы найдете что-нибудь, что может помочь, поделитесь, пожалуйста. Спасибо. - person António Quadrado; 24.10.2016
comment
На самом деле в таких случаях мой первый выбор - не слишком сильно связываться с конфигурацией webpack. Причина в том, что поддерживать и объяснять другим членам команды становится кошмаром. Вот почему я не хотел углубляться в эту страницу с проблемами github о том, как другим удалось это обойти. Вместо этого должно быть проще изменить дизайн приложения, чтобы избежать циклического импорта. Но если я найду простой способ, я вернусь и отредактирую свой ответ выше. - person Mani; 24.10.2016
comment
Мне не нужно менять дизайн своего приложения из-за ограничений веб-пакета. В контексте приложения имеет смысл иметь подобную структуру компонентов. Я действительно надеюсь, что есть обходной путь к этому ... - person António Quadrado; 24.10.2016
comment
Да, я согласен с тобой. Подождем еще ответов на ваш вопрос. Пожалуйста, держите его в открытом состоянии, чтобы его заметили другие. Даже я хотел бы получить на это ответ, поскольку это вопрос времени, когда я столкнусь с ситуацией, подобной вашей. - person Mani; 24.10.2016
comment
Я столкнулся с точной проблемой. Любая дополнительная информация будет принята с благодарностью. @ AntónioQuadrado Вы нашли решение этой проблемы? - person mythicalcoder; 20.08.2017

На самом деле существует хорошая документация. и некоторые другие решения этой проблемы, такие как использование асинхронного импорта Webpack или глобальная регистрация необходимых компонентов.

<template>
    <div>
        <span>Hi, I'm component A!</span>
        <component-a></component-a>
    </div>
</template>

<script>
    export default {
      name: 'component-b',
      components: {
         // async import: 
         ComponentA: () => import('./ComponentA.vue')
      }
  }
</script>
person Andrew Rendall    schedule 03.06.2020