Как обойти требование только одного корневого элемента в компоненте vue?

#vue.js #vue-component #css-grid

Вопрос:

У меня есть случай, когда я не могу придумать никакого другого решения, которое решило бы мою проблему. Моя задача состоит в том, чтобы расположить элементы в сетке css, эти элементы могут быть либо загрузочной картой, либо списком карт, либо списком списков…или списком списков списков и так далее. В конце концов все всегда сводится к карточке. Как вы, наверное, уже догадались, для этого мне нужна рекурсия. Итак, у меня есть компонент карты, код которого не имеет отношения к моему вопросу, поэтому я не буду его включать. У меня также есть компонент-оболочка, как показано ниже

 <template>
    <div class="container-fluid" >
        <div class="wrapper-content">
            <template v-for="item in items">
                <content-display :expand="expand" :item="item" :params="params" :param="neededParam(item.id)" :key="item.id"></content-display>
            </template>
        </div>
    </div>    
</template>
<script>

<style>
    .wrapper-content {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
        grid-auto-rows: auto;
        grid-gap: 1em;
    }
</style>
 

Затем у меня также есть компонент отображения содержимого , который либо использует компонент карты, либо компонент списка

   <template>
    <div>
        <template v-for="item in items">
            <list-component v-if="expand" :params="params" :param="param" :key="item.id" :item="item" :is="item.object_type.ModelName"></list-component>
            <object-card v-else :key="item.id" :item="item" :param="param"></object-card>
        </template>
    </div>
    
</template>
 

И, наконец, вот компонент списка

 <template>
    <object-card v-if="!expand" :item="item" :param="param">
    </object-card>
    <content-display v-else :items="item.entity.list_objects" :params="params">
    </content-display>
</template>
 

Моя проблема заключается в компоненте отображения содержимого, мне нужно, чтобы карты были прямыми дочерними узлами сетки, однако с ограничением Vue я не могу этого достичь, потому что мне нужна внешняя оболочка div, и поэтому вместо этого

 <div class="container-fluid" >
        <div class="wrapper-content">
            <div class="card"></div>
            <div class="card"></div>
            <div class="card"></div>
            <div class="card"></div>
            <div class="card"></div>
            <div class="card"></div>
            <div class="card"></div>
        </div>
    </div>    
 

Я понимаю это

 <div class="wrapper-content">
            <div class="card"></div>
            <div class="card"></div>
            <div>
                <div class="card"></div>
                <div class="card"></div>
            </div>
            <div class="card"></div>
            <div class="card"></div>
            <div class="card"></div>
        </div>
 

Примечание: Я думал об использовании style="grid-column: 1 / -1;" этого внешнего div, а затем иметь внутри него другую сетку, но мой сгенерированный html был бы очень грязным.

Ответ №1:

Используйте Vue 3 — у него нет этого ограничения.

Но если вы используете Vue 2, то попробуйте VueFragment

 const Fragments = window.VFragments
const Fragment = Fragments.VFragment

new Vue({
  el: "#app",
  components: {
    Fragment,
  },
}) 
 .grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@superyusuke/vue-fragment@1.0.0/dist/vue-fragments.min.js"></script>
<div id="app" class="grid-container">
  <fragment>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
  </fragment>
</div> 

Вы можете видеть, что <fragment> это «обходится» стороной CSS Grid .

Комментарии:

1. Хотя я получаю сообщение об ошибке «Не удалось выполнить «removeChild» на «Узле»: Узел, подлежащий удалению, не является дочерним по отношению к этому узлу». Возможно, вы знаете, в чем причина этого?

2. @Matrix к сожалению, это может произойти — я читал об этом здесь , так что есть люди, которым больше нравится vue-frag