Как отрендерить дочерние компоненты в VueJS?

Есть компонент Comp1, который может принимать в себя любые компоненты в любом порядке и количестве.

<Comp1>
  <div>Content</div>
  <span>Content</span>
  <SomeComp/>
</Comp1>

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

Пример вывода:

<Comp1>
  <div>
    <div>Content</div>
  </div>
  <div>
    <span>Content</span>
  </div>
  <div>
    <SomeComp/>
  </div>
</Comp1>

Как можно это реализовать в VueJS?


Ответы (1 шт):

Автор решения: Vasiliy Rusin

По моему личному мнению, данный патерн нужно использовать с крайней осторожностью, он не расширяем верятнее будет правильнее использовать v-for и явно обернуть каждое значение в тег.

Как Вы верно заметили в обсуждении, в реакте это делается давольно просто. Чтож Vue не запрещает использование JSX. Comp1 будет выглядеть так

<script>
    export default {
        name: "Comp1",
        props: {
            tag: {
                type: [String, Object],
                default: "div"
            },
            
            wrapper: {
                type: [String, Object],
                default: "div"
            }
        },
        
        render (createElement) {
            return createElement(
                this.tag,
                this.$slots.default.map(
                    el => createElement(this.wrapper, [el])
                )
            )
        }
    };
</script>

Здесь у нас есть два пропса, первый tag задает тег который будет ипользоваться вместо самого компонета, второй wrapper будет использоваться для оберток. Например

<Comp1 tag="ul" wrapper="li"></Comp1>

создаст список из значений переданных в Comp1.

Так же можно использовать дугие компонеты как обертки, если они реализуют собственный слот.

<Comp1 tag="ul" :wrapper="CompWithSlot"></Comp1>
→ Ссылка